適切な「戻る」ナビゲーションを提供する

「戻る」ナビゲーションとは、ユーザーがこれまでにアクセスした画面の履歴を遡って移動する機能です。すべての Android デバイスに、このタイプのナビゲーション用の [戻る] ボタンがあるため、アプリの UI には [戻る] ボタンを追加しないでください。ユーザーの Android デバイスによっては、このボタンが物理ボタンの場合もあれば、ソフトウェア ボタンの場合もあります。

Android は、ユーザーがアプリ内を移動する際、デスティネーションのバックスタックを保持します。これにより、[戻る] ボタンが押されたときに Android は前のデスティネーションに適切に移動できます。ただし、最適なユーザー エクスペリエンスを提供するために、独自の「戻る」動作をアプリに実装しなければならない場合もあります。

たとえば、WebView を使用する場合、[戻る] ボタンのデフォルトの動作をオーバーライドして、ユーザーがアプリの前の画面ではなくウェブ 閲覧履歴に戻るようにできます。

Android 13 以降では、Android デバイス向けの予測型「戻る」ジェスチャーを利用できます。この機能について詳しくは、予測型「戻る」ジェスチャーのサポートを追加するをご覧ください。

カスタムの「戻る」ナビゲーションを実装する

FragmentActivityAppCompatActivity の基本クラスである ComponentActivity を使用すると、戻るボタンの動作を制御することができます。これを getOnBackPressedDispatcher() を呼び出して取得できます。OnBackPressedDispatcher

OnBackPressedDispatcher は、[戻る] ボタンイベントを 1 つまたは複数の OnBackPressedCallback オブジェクトにディスパッチする方法を制御します。OnBackPressedCallback のコンストラクタは、初期有効状態のブール値を取ります。コールバックが有効になっている場合(isEnabled()true を返す場合)、ディスパッチャはコールバックの handleOnBackPressed() を呼び出して [戻る] ボタンイベントを処理します。有効状態を変更するには、setEnabled() を呼び出します。

コールバックは addCallback メソッドを使用して追加します。LifecycleOwner を受け取る addCallback() メソッドを使用することをおすすめします。これにより、LifecycleOwnerLifecycle.State.STARTED の場合に限り、OnBackPressedCallback が追加されるようになります。また、アクティビティは、関連付けられた LifecycleOwner が破棄されたときに、登録済みのコールバックを削除します。これにより、メモリリークが防止され、LifecycleOwner は、アクティビティよりも存続期間が短いフラグメントや他のライフサイクル オーナーでの使用に適しています。

コールバックの実装例を次に示します。

Kotlin

class MyFragment : Fragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // This callback is only called when MyFragment is at least started
        val callback = requireActivity().onBackPressedDispatcher.addCallback(this) {
            // Handle the back button event
        }

        // The callback can be enabled or disabled here or in the lambda
    }
    ...
}

Java

public class MyFragment extends Fragment {

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // This callback is only called when MyFragment is at least started
        OnBackPressedCallback callback = new OnBackPressedCallback(true /* enabled by default */) {
            @Override
            public void handleOnBackPressed() {
                // Handle the back button event
            }
        };
        requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);

        // The callback can be enabled or disabled here or in handleOnBackPressed()
    }
    ...
}

addCallback() を使用して複数のコールバックを指定できます。追加すると、コールバックは追加した順序とは逆の順序で呼び出されます。つまり、最後に追加されたコールバックが、[戻る] ボタンイベントを処理する機会を最初に与えることになります。たとえば、onetwothree という名前の 3 つのコールバックを追加すると、threetwoone の順序で呼び出されます。

コールバックは、「チェーン オブ レスポンシビリティ」パターンに従います。チェーン内の各コールバックが呼び出されるのは、前のコールバックが有効になっていない場合に限られます。つまり、上記の例では、コールバック two はコールバック three が有効になっていない場合にのみ呼び出され、コールバック one はコールバック two が有効になっていない場合にのみ呼び出されます。

なお、addCallback() を使用してコールバックを追加した場合、LifecycleOwnerLifecycle.State.STARTED 状態に入るまで、コールバックは一連の責任チェーンに追加されません。

一時的な変更のために OnBackPressedCallback の有効状態を変更することをおすすめします。そうすることで、上記の順序が維持されます。これは、ネストされた複数のライフサイクル オーナーにコールバックを登録している場合に特に重要です。

OnBackPressedCallback を完全に削除する場合は、remove() を呼び出します。コールバックは、関連付けられている LifecycleOwner破棄されると自動的に削除されるため、通常はこれは必要ありません。

onBackPressed() アクティビティ

[戻る] ボタンイベントの処理に onBackPressed() を使用している場合は、代わりに OnBackPressedCallback を使用することをおすすめします。ただし、この変更に対応できない場合は、次のルールが適用されます。

  • addCallback を通じて登録するコールバックはすべて、super.onBackPressed() を呼び出したときに評価されます。
  • Android 12(API レベル 32)以前では、登録された OnBackPressedCallback インスタンスに関係なく、常に onBackPressed が呼び出されます。