「戻る」ナビゲーションとは、ユーザーがこれまでにアクセスした画面の履歴を遡って移動する機能です。すべての Android デバイスに、このタイプのナビゲーション用の [戻る] ボタンがあるため、アプリの UI には [戻る] ボタンを追加しないでください。ユーザーの Android デバイスによっては、このボタンが物理ボタンの場合もあれば、ソフトウェア ボタンの場合もあります。
Android は、ユーザーがアプリ内を移動する際、デスティネーションのバックスタックを保持します。これにより、[戻る] ボタンが押されたときに Android は前のデスティネーションに適切に移動できます。ただし、最適なユーザー エクスペリエンスを提供するために、独自の「戻る」動作をアプリに実装しなければならない場合もあります。
たとえば、WebView
を使用する場合、[戻る] ボタンのデフォルトの動作をオーバーライドして、ユーザーがアプリの前の画面ではなくウェブ 閲覧履歴に戻るようにできます。
Android 13 以降では、Android デバイス向けの予測型「戻る」ジェスチャーを利用できます。この機能について詳しくは、予測型「戻る」ジェスチャーのサポートを追加するをご覧ください。
カスタムの「戻る」ナビゲーションを実装する
FragmentActivity
と AppCompatActivity
の基本クラスである ComponentActivity
を使用すると、戻るボタンの動作を制御することができます。これを getOnBackPressedDispatcher()
を呼び出して取得できます。OnBackPressedDispatcher
OnBackPressedDispatcher
は、[戻る] ボタンイベントを 1 つまたは複数の OnBackPressedCallback
オブジェクトにディスパッチする方法を制御します。OnBackPressedCallback
のコンストラクタは、初期有効状態のブール値を取ります。コールバックが有効になっている場合(isEnabled()
が true
を返す場合)、ディスパッチャはコールバックの handleOnBackPressed()
を呼び出して [戻る] ボタンイベントを処理します。有効状態を変更するには、setEnabled()
を呼び出します。
コールバックは addCallback
メソッドを使用して追加します。LifecycleOwner
を受け取る addCallback()
メソッドを使用することをおすすめします。これにより、LifecycleOwner
が Lifecycle.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()
を使用して複数のコールバックを指定できます。追加すると、コールバックは追加した順序とは逆の順序で呼び出されます。つまり、最後に追加されたコールバックが、[戻る] ボタンイベントを処理する機会を最初に与えることになります。たとえば、one
、two
、three
という名前の 3 つのコールバックを追加すると、three
、two
、one
の順序で呼び出されます。
コールバックは、「チェーン オブ レスポンシビリティ」パターンに従います。チェーン内の各コールバックが呼び出されるのは、前のコールバックが有効になっていない場合に限られます。つまり、上記の例では、コールバック two
はコールバック three
が有効になっていない場合にのみ呼び出され、コールバック one
はコールバック two
が有効になっていない場合にのみ呼び出されます。
なお、addCallback()
を使用してコールバックを追加した場合、LifecycleOwner
が Lifecycle.State.STARTED
状態に入るまで、コールバックは一連の責任チェーンに追加されません。
一時的な変更のために OnBackPressedCallback
の有効状態を変更することをおすすめします。そうすることで、上記の順序が維持されます。これは、ネストされた複数のライフサイクル オーナーにコールバックを登録している場合に特に重要です。
OnBackPressedCallback
を完全に削除する場合は、remove()
を呼び出します。コールバックは、関連付けられている LifecycleOwner
が破棄されると自動的に削除されるため、通常はこれは必要ありません。
onBackPressed() アクティビティ
[戻る] ボタンイベントの処理に onBackPressed()
を使用している場合は、代わりに OnBackPressedCallback
を使用することをおすすめします。ただし、この変更に対応できない場合は、次のルールが適用されます。
addCallback
を通じて登録するコールバックはすべて、super.onBackPressed()
を呼び出したときに評価されます。- Android 12(API レベル 32)以前では、登録された
OnBackPressedCallback
インスタンスに関係なく、常にonBackPressed
が呼び出されます。