「戻る」ナビゲーションとは、ユーザーがこれまでにアクセスした画面の履歴を遡って移動する機能です。すべての Android デバイスにこのナビゲーション タイプ用の [戻る] ボタンが用意されているため、アプリの UI には [戻る] ボタンを追加しないでください。ユーザーの Android デバイスによっては、このボタンが物理ボタンの場合もあれば、ソフトウェア ボタンの場合もあります。
Android は、ユーザーがアプリ内を移動する際、デスティネーションのバックスタックを保持します。これにより、通常は [戻る] ボタンを押すと、以前のデスティネーションに適切に移動できます。ただし、可能な限り最高のユーザー エクスペリエンスを提供するために、アプリ独自の [戻る] 動作を実装する必要性が生じることがあります。たとえば、WebView
を使用している場合、デフォルトの [戻る] ボタンの動作をオーバーライドして、アプリ内の前の画面ではなく、ウェブ閲覧履歴をさかのぼれるようにできます。
カスタムの「戻る」ナビゲーションを実装する
FragmentActivity
および AppCompatActivity
の基本クラスである ComponentActivity
では、getOnBackPressedDispatcher()
を呼び出して取得できる OnBackPressedDispatcher
を使用して、[戻る] ボタンの動作を制御できます。
OnBackPressedDispatcher
は、[戻る] ボタンイベントを 1 つまたは複数の OnBackPressedCallback
オブジェクトにディスパッチする方法を制御します。OnBackPressedCallback
のコンストラクタは、初期有効状態のブール値を取ります。コールバックが有効になっている場合(つまり、
isEnabled()
が true
を返す場合)に限り、ディスパッチャはコールバックの handleOnBackPressed()
を呼び出して、[戻る] ボタンイベントを処理します。有効状態を変更するには、setEnabled()
を呼び出します。
コールバックは、addCallback
メソッドを通じて追加されます。LifecycleOwner
を取る addCallback()
メソッドを使用することを強くおすすめします。これにより、LifecycleOwner
が Lifecycle.State.STARTED
の場合に限り、OnBackPressedCallback
が追加されるようになります。また、対象の LifecycleOwner
が破棄されると、アクティビティによって、登録済みコールバックが削除されます。これにより、メモリリークが防止されるため、アクティビティよりも寿命が短いフラグメントや各種ライフサイクル オーナー内で使用する場合に適しています。
コールバック実装の例を以下に示します。
Kotlin
class MyFragment : Fragment() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // This callback will only be 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 will only be 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
という順序で呼び出されます。
コールバックは、「チェーン オブ レスポンシビリティ」パターンに従います。チェーン内の各コールバックが呼び出されるのは、前のコールバックが有効になっていない場合に限られます。つまり、上記の例の場合、コールバック three
が有効状態でない場合に限り、コールバック two
が呼び出されます。同様に、コールバック two
が有効状態でない場合に限り、コールバック one
が呼び出されます。
なお、addCallback()
を通じてコールバックを追加する場合、LifecycleOwner
が Lifecycle.State.STARTED
状態になるまで、コールバックは「チェーン オブ レスポンシビリティ」には追加されません。
上記で説明した順序を維持するため、OnBackPressedCallback
の有効状態を変更する場合は、一時的な変更にとどめておくことを強くおすすめします。この点は特に、複数のネスト ライフサイクル オーナーに対してコールバックを登録する場合に重要になります。
他方、OnBackPressedCallback
を完全に削除する場合は、remove()
を呼び出します。ただし、対象の LifecycleOwner
が破棄されるとコールバックも自動的に削除されるため、この処理は通常必要ありません。
onBackPressed() アクティビティ
onBackPressed()
を使用して [戻る] ボタンイベントを処理している場合は、代わりに OnBackPressedCallback
を使用することをおすすめします。ただし、この変更に対応できない場合は、次のルールが適用されます。
addCallback
を通じて登録するコールバックはすべて、super.onBackPressed()
を呼び出したときに評価されます。- Android 12(API レベル 32)以前では、登録された
OnBackPressedCallback
インスタンスに関係なく、常にonBackPressed
が呼び出されます。