在 Wear 上退出全屏 Activity

用户可通过从左向右滑动来退出 Wear OS Activity。如果应用提供水平滚动方式(例如,包含地图的应用中提供的滚动方式),用户则可通过导航到内容边缘而后从左向右滑动来退出。

按电源按钮会让用户返回到表盘。

请参阅以下相关资源:

滑动关闭手势

用户从左向右滑动即可关闭当前屏幕。因此,建议您利用以下资源:

此外,还建议您不要在应用中添加水平滑动手势。

关闭 Activity

Activity 自动支持滑动关闭。从左向右滑动 Activity 可使 Activity 关闭,并且应用会沿着返回堆栈逐层返回。

Fragment

您可以在 SwipeDismissFrameLayout 类中封装一个包含 Fragment 的视图,如下所示:

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;
        }
    }
    

注意:在穿戴式设备支持库中,SwipeDismissFrameLayout 类取代了一个与其相似的已弃用类。

水平可滚动视图

在某些情况下(例如,视图包含支持平移的地图),界面不会阻止水平滑动。在这种情况下,有两种选择:

  • 如果返回堆栈较短,用户可通过按电源按钮来关闭应用并返回主屏幕(表盘)。
  • 如果您希望用户沿着返回堆栈逐层返回,可以将视图封装在一个支持边缘滑动的 SwipeDismissFrameLayout 对象中。如果视图或其子项从 canScrollHorizontally() 调用返回 true,就表示边缘滑动处于启用状态。借助边缘滑动,用户不仅可在视图中的任意位置滑动来关闭视图,而且还能从屏幕最左侧(目前设为屏幕宽度的 10%)滑动来关闭视图。

要将视图封装在 SwipeDismissFrameLayout 对象中,请查看以下示例:

布局文件的 XML

    <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);
        }
      }
    );
    

一般不建议停用滑动关闭

一般不建议停用滑动关闭,因为用户希望通过滑动来关闭任何屏幕。在例外情况下,您可以扩展默认主题背景(在样式资源中),并将 android:windowSwipeToDismiss 属性设为 false

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

然后您就可以通知用户(在他们首次使用您的应用时),他们可通过按电源按钮来退出应用。

Wear 2.0 之前的关闭行为

在 Wear 2.0 之前,使用 DismissOverlayView 类来实现长按操作,供用户用于关闭应用。现在,不再使用 DismissOverlayView类。

此外,也不建议通过长按来关闭应用。请勿实现通过长按关闭全屏 Activity(如 Google 地图这类平移或沉浸式 Activity)。

通过电源按钮关闭

按电源(硬件)按钮会发送电源键事件。因此,您不能将电源按钮用作返回按钮或用于一般导航。

按电源按钮会让用户返回主屏幕(表盘)。有两种例外情况:

  • 如果用户正在使用输入法(例如,手写识别屏幕),则按电源按钮会关闭输入法并让用户返回应用。
  • 如果用户正在表盘上,按硬件按钮会打开应用启动器。

请注意,按电源按钮时,Activity 类的 isFinishing() 方法不会返回 true(您也无法截获按键事件)。