Thoát khỏi hoạt động toàn màn hình trên Wear

Người dùng có thể thoát khỏi một hoạt động Wear OS bằng cách vuốt từ trái sang phải. Nếu ứng dụng có tính năng cuộn ngang, người dùng có thể thoát bằng cách di chuyển đến cạnh nội dung rồi vuốt từ trái sang phải. Việc nhấn nút nguồn cũng đưa người dùng trở lại mặt đồng hồ

Cử chỉ 'vuốt để đóng'

Người dùng có thể vuốt từ trái sang phải để đóng màn hình hiện tại. Vì vậy, bạn nên sử dụng thành phần giao diện người dùng sau:

  • Bố cục dọc
  • Vùng chứa nội dung

Bạn cũng nên tránh sử dụng cử chỉ vuốt ngang trong ứng dụng của mình.

Đóng hoạt động

Hoạt động sẽ tự động hỗ trợ việc 'vuốt để đóng' Việc vuốt từ trái sang phải một hoạt động sẽ đóng lại hoạt động đó, và ứng dụng sẽ quay lại trạng thái trước đó trong ngăn xếp lui.

Đóng mảnh

Nhằm hỗ trợ việc 'vuốt để đóng' mảnh, bạn phải gói chế độ xem chứa mảnh này vào lớp SwipeDismissFrameLayout. Hãy cân nhắc việc này khi quyết định có dùng đến mảnh hay không. Hãy dùng lớp SwipeDismissFrameLayout như ví dụ dưới đây:

Kotlin

class SwipeDismissFragment : Fragment() {
    private val callback = object : SwipeDismissFrameLayout.Callback() {
        override fun onSwipeStarted(layout: SwipeDismissFrameLayout) {
            // Optional
        }

        override fun onSwipeCanceled(layout: SwipeDismissFrameLayout) {
            // Optional
        }

        override fun onDismissed(layout: SwipeDismissFrameLayout) {
            // Code here for custom behavior, such as going up the
            // back stack and destroying the fragment but staying in the app.
        }
    }

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View =
            SwipeDismissFrameLayout(activity).apply {

                // If the fragment should fill the screen (optional), then in the layout file,
                // in the androidx.wear.widget.SwipeDismissFrameLayout element,
                // set the android:layout_width and android:layout_height attributes
                // to "match_parent".

                inflater.inflate(
                        R.layout.swipe_dismiss_frame_layout,
                        this,
                        false
                ).also { inflatedView ->
                    addView(inflatedView)
                }
                addCallback(callback)
            }
}

Java

public class SwipeDismissFragment extends Fragment {
  private final Callback callback =
    new Callback() {
      @Override
        public void onSwipeStart() {
          // Optional
        }

        @Override
        public void onSwipeCancelled() {
          // Optional
        }

        @Override
        public void onDismissed(SwipeDismissFrameLayout layout) {
          // Code here for custom behavior, such as going up the
          // back stack and destroying the fragment but staying in the app.
        }
      };

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    SwipeDismissFrameLayout swipeLayout = new SwipeDismissFrameLayout(getActivity());

    // If the fragment should fill the screen (optional), then in the layout file,
    // in the androidx.wear.widget.SwipeDismissFrameLayout element,
    // set the android:layout_width and android:layout_height attributes
    // to "match_parent".

    View inflatedView = inflater.inflate(R.layout.swipe_dismiss_frame_layout, swipeLayout, false);
    swipeLayout.addView(inflatedView);
    swipeLayout.addCallback(callback);

    return swipeLayout;
    }
}

Lưu ý: Khi sử dụng mảnh trong hoạt động của bạn, hãy ưu tiên sử dụng FragmentManager.add hơn là FragmentManager.replace để hỗ trợ cử chỉ 'vuốt để đóng'. Việc này giúp đảm bảo rằng mảnh đang hoạt động trước đó hiện dưới mảnh đang hoạt động sau khi mảnh này bị vuốt mất.

Chế độ xem có thể cuộn theo chiều ngang

Trong một số trường hợp, chẳng hạn như chế độ xem chứa bản đồ có thể xoay, giao diện người dùng không thể loại bỏ cử chỉ vuốt ngang. Trong trường hợp này, bạn sẽ có 2 lựa chọn:

  • Nếu ngăn xếp lui không nhiều, người dùng có thể đóng ứng dụng và quay lại màn hình chính của mặt đồng hồ bằng cách nhấn nút nguồn.
  • Nếu bạn muốn người dùng trở lại hoạt động trước trong ngăn xếp lui, bạn có thể gói chế độ xem trong đối tượng SwipeDismissFrameLayout (hỗ trợ việc vuốt từ cạnh). Khi chế độ xem hoặc con của chế độ xem trả về giá trị true từ lệnh gọi canScrollHorizontally(), người dùng có thể vuốt từ cạnh. Việc vuốt từ cạnh sẽ giúp người dùng đóng chế độ xem bằng cách vuốt từ điểm ngoài cùng bên trái, chiếm 10% diện tích màn hình, chứ không phải từ bất kỳ vị trí nào khác.

Ví dụ dưới đây minh hoạ cách gói chế độ xem vào trong một đối tượng SwipeDismissFrameLayout:

<androidx.wear.widget.SwipeDismissFrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/swipe_dismiss_root" >

    <TextView
        android:id="@+id/test_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="Swipe me to dismiss me." />
</androidx.wear.widget.SwipeDismissFrameLayout>

Kotlin

activity?.findViewById<SwipeDismissFrameLayout>(R.id.swipe_dismiss_root)?.apply {
    addCallback(object : SwipeDismissFrameLayout.Callback() {

        override fun onDismissed(layout: SwipeDismissFrameLayout) {
            layout.visibility = View.GONE
        }
    })
}

Java

SwipeDismissFrameLayout testLayout =
    (SwipeDismissFrameLayout) activity.findViewById(R.id.swipe_dismiss_root);
testLayout.addCallback(new SwipeDismissFrameLayout.Callback() {
    @Override
    public void onDismissed(SwipeDismissFrameLayout layout) {
        layout.setVisibility(View.GONE);
    }
  }
);

Không nên áp dụng: Vô hiệu hoá 'vuốt để đóng'

Nhìn chung, bạn không nên vô hiệu hoá việc 'vuốt để đóng', vì người dùng mong muốn có thể đóng bất kỳ màn hình nào chỉ bằng một thao tác vuốt. Trong một số trường hợp đặc biệt, bạn có thể mở rộng giao diện mặc định trong một tài nguyên kiểu rồi đặt thuộc tính android:windowSwipeToDismiss thành false, như mã mẫu dưới đây:

<resources>
  <style name="AppTheme" parent="@android:style/Theme.DeviceDefault">
    <item name="android:windowSwipeToDismiss">false</item>
  </style>
</resources>

Sau đó, bạn có thể thông báo người dùng trong lần sử dụng ứng dụng đầu tiên rằng họ có thể thoát khỏi ứng dụng bằng cách nhấn nút nguồn.

Đóng bằng nút nguồn

Việc nhấn nút nguồn trong thực tế sẽ gửi một sự kiện liên quan đến phím nguồn. Vì vậy, bạn không thể đặt nút nguồn thành nút quay lại hoặc để điều hướng nói chung.

Khi được nhấn, nút nguồn sẽ đưa người dùng trở lại màn hình chính của mặt đồng hồ. Có 2 trường hợp ngoại lệ:

  • Nếu người dùng đang trong một Trình chỉnh sửa phương thức nhập (IME), chẳng hạn như màn hình nhận dạng chữ viết tay, việc nhấn nút sẽ đóng lại Trình chỉnh sửa này và đưa người dùng trở lại ứng dụng.
  • Nếu người dùng đang ở màn hình chính của mặt đồng hồ, việc nhấn nút phần cứng sẽ mở trình khởi chạy ứng dụng.

Lưu ý rằng khi người dùng nhấn nút nguồn, phương thức isFinishing() của lớp Activity sẽ không thể trả về true, dẫn đến việc cản trở sự kiện liên quan đến phím.

Để biết thêm thông tin, hãy xem bài viết Điều hướng.