Wear で全画面表示のアクティビティを終了する

ユーザーは、左から右にスワイプすることによって Wear OS のアクティビティを終了できます。アプリに水平スクロール機能(地図を含むアプリで利用できるタイプのスクロール機能など)がある場合、ユーザーはコンテンツの端で、左から右にスワイプすることによって終了できます。

電源ボタンを押すと、ウォッチフェイスに戻ります。

以下の関連リソースもご覧ください。

スワイプして閉じる操作

ユーザーは左から右にスワイプすることによって現在の画面を閉じることができます。そのため、以下を利用することをおすすめします。

また、水平方向のスワイプ操作はアプリに含めないことをおすすめします。

アクティビティの終了

アクティビティは、スワイプして閉じる操作を自動サポートしています。アクティビティを左から右にスワイプすると、アクティビティが終了し、アプリがバックスタックに移動します。

フラグメント

次のように、フラグメントを含むビューを SwipeDismissFrameLayout クラスにラップすることができます。

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 android.support.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 android.support.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 は、ウェアラブル サポート ライブラリのサポートが終了した類似のクラスの後継クラスです。

水平スクロールが可能なビュー

パンをサポートする地図を含むビューなどでは、ユーザー インターフェースによって水平方向のスワイプが妨げられることがあります。このようなシナリオでは、次の 2 つの選択肢があります。

  • バックスタックが短い場合、ユーザーは電源ボタンを押すことによってアプリを閉じ、ホーム画面(ウォッチフェイス)に戻ることができます。
  • ユーザーをバックスタックに移動させたい場合は、エッジスワイプをサポートする SwipeDismissFrameLayout オブジェクトにビューをラップできます。canScrollHorizontally() を呼び出した結果、ビューまたはその子が true を返すと、エッジスワイプが有効化されます。エッジスワイプでは、ビューの任意の場所だけでなく、画面の左端(現在は画面の幅の 10% に設定されています)からスワイプすることによってビューを閉じることができます。

SwipeDismissFrameLayout オブジェクトにビューをラップする場合は、以下の例をご確認ください。

レイアウト ファイルの XML

    <android.support.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." />
    </android.support.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 クラスは使用できなくなっています。

また、長押しによるアプリの終了は、現在は推奨されていません。全画面表示のアクティビティ(Google マップなどのパンまたは没入型アクティビティ)を終了するために長押しをしないでください。

電源ボタンによる終了

電源(ハードウェア)ボタンを押すと、電源キーイベントが送信されます。このため通常は、電源ボタンを戻るボタンとして、または移動用に使用することはできません。

ユーザーが電源ボタンを押すと、ホーム画面(ウォッチフェイス)に戻ります。ただし、次の 2 つの例外があります。

  • ユーザーが IME(手書き入力認識画面など)の操作中にボタンを押すと、IME が終了し、アプリに戻ります。
  • ウォッチフェイスが表示されているときにユーザーがハードウェア ボタンを押すと、アプリ ランチャーが起動します。

電源ボタンが押されたとき、Activity クラスの isFinishing() メソッドは true を返しません(キーイベントをインターセプトすることもできません)。