予測型「戻る」ジェスチャーのサポートを追加する

図 1. スマートフォンでの予測型「戻る」ジェスチャーのデザインを示すモックアップ

予測型「戻る」は、ジェスチャー ナビゲーション機能であり、「戻る」スワイプで移動する場所をプレビューできます。

たとえば図 1 のモックアップに示すように、「戻る」ジェスチャーによって、アプリの背後にあるホーム画面のアニメーション プレビューを表示できます。

Android 15 以降、予測型「戻る」アニメーションの開発者向けオプションは利用できなくなりました。予測型「戻る」ジェスチャーを全体またはアクティビティ レベルで有効にしているアプリで、「ホームに戻る」、タスク間、アクティビティ間などのシステム アニメーションが表示されるようになりました。

このホームに戻るアニメーションをテストできます(このページの後続のセクションを参照)。

予測型「戻る」ジェスチャーをサポートするには、AndroidX Activity 1.6.0 以降の API で下位互換性のある OnBackPressedCallback を使用するか、新しい OnBackInvokedCallback プラットフォーム API を使用して、アプリを更新する必要があります。ほとんどのアプリでは、下位互換性のある AndroidX API を使用します。

この更新は、「戻る」ナビゲーションを正しくインターセプトするための移行パスを提供するもので、KeyEvent.KEYCODE_BACK からの「戻る」インターセプトや、onBackPressed メソッドを含むクラス(Activity、Dialog など)を、新しいシステムの「戻る」API で置き換えるためのものです。

Codelab と Google I/O の動画

ドキュメントのこのページの内容に加えて、Codelab もお試しください。AndroidX のアクティビティ API を使用して予測型「戻る」ジェスチャーを処理する WebView の一般的なユースケース実装を参照できます。

AndroidX とプラットフォームの API を実装する例については、Google I/O の動画もご覧ください。

Compose でカスタムの「戻る」ジェスチャーを処理する

Compose には、カスタムの「戻る」操作を処理する PredictiveBackHandler コンポーザブルが用意されています。この API を使用すると、戻る操作に対応できます。また、BackEventCompat オブジェクトの Flow が提供されるため、ユーザーがスワイプしたときにカスタム アニメーションや遷移を実装できます。

PredictiveBackHandler を使用するには、アプリに androidx.activity:activity-compose 依存関係(バージョン 1.8.0 以降)が含まれていることを確認します。

// In your build.gradle.kts file:
dependencies {
    implementation("androidx.activity:activity-compose:1.8.0")
}

PredictiveBackHandler(enabled = isBackHandlerEnabled) { progress: Flow<BackEventCompat> ->
    try {
        progress.collect { backEvent ->
            // Update your UI or animation based on backEvent.progress.
        }
        // Handle the final back action (e.g., navigate back).
    } catch (e: CancellationException) {
        // Back gesture was cancelled, reset your UI.
    }
}

進行状況をトラッキングせずに「戻る」操作をインターセプトするだけでよい場合は、BackHandler を使用します。

デフォルトの「戻る」ナビゲーションを使用するアプリを更新する

予測型「戻る」はデフォルトで有効になっています。

アプリでフラグメントや Navigation コンポーネントを使用している場合は、AndroidX Activity 1.6.0 以降へのアップグレードも行ってください。

カスタムの「戻る」ナビゲーションを使用するアプリを更新する

アプリにカスタム「戻る」動作が実装されている場合は、AndroidX 使用の有無や「戻る」ナビゲーションの処理方法に応じて移行パスが異なります。

アプリでの「戻る」ナビゲーションの処理方法 おすすめの移行パス(このページのリンク)
AndroidX API AndroidX の既存の「戻る」動作を移行する
サポートされていないプラットフォーム API サポート対象外の「戻る」ナビゲーション API を含む AndroidX アプリを AndroidX API に移行する

AndroidX の「戻る」ナビゲーションの実装を移行する

このユースケースが最も一般的なおすすめの方法です。これは、OnBackPressedDispatcher によってカスタム ジェスチャー ナビゲーションを処理する、新規と既存両方のアプリに当てはまります(適切な「戻る」ナビゲーションを提供するを参照)。

すでに OnBackPressedDispatcher を使用している API(フラグメントや Navigation コンポーネントなど)が、予測型「戻る」ジェスチャーとシームレスに連携するように、AndroidX Activity 1.6.0 以降にアップグレードします。

// In your build.gradle file:
dependencies {
    // Add this in addition to your other dependencies
    implementation "androidx.activity:activity:1.6.0"
}

サポート対象外の「戻る」ナビゲーション API を含む AndroidX アプリを AndroidX API に移行する

アプリで AndroidX ライブラリを使用しながら、サポートされていない「戻る」ナビゲーション API を実装または参照している場合は、AndroidX API に移行して新しい動作をサポートする必要があります。

サポートされていない API を AndroidX API に移行する手順は次のとおりです。

  1. OnBackPressedCallback の実装を使用して、システムの「戻る」ナビゲーション処理ロジックを AndroidX の OnBackPressedDispatcher に移行します。詳細なガイダンスについては、適切な「戻る」ナビゲーションを提供するをご覧ください。

  2. 「戻る」ジェスチャーのインターセプトを停止する準備ができたら、OnBackPressedCallback を無効にします。

  3. OnBackPressed または KeyEvent.KEYCODE_BACK による「戻る」イベントのインターセプトを停止します。

  4. 必ず AndroidX Activity 1.6.0 以降にアップグレードしてください。

    // In your build.gradle file:
    dependencies {
        // Add this in addition to your other dependencies
        implementation "androidx.activity:activity:1.6.0"
    }
    

予測型「戻る」をオプトアウトする

オプトアウトするには、AndroidManifest.xml の <application> タグ内で、android:enableOnBackInvokedCallback フラグを false に設定します。

<application
    ...
    android:enableOnBackInvokedCallback="false"
    ... >
...
</application>

これを false に設定すると、次のようになります。

  • 予測型「戻る」ジェスチャーのシステム アニメーションが無効になります。
  • OnBackInvokedCallback は無視されますが、OnBackPressedCallback 呼び出しは引き続き機能します。

アクティビティ レベルでオプトアウトする

android:enableOnBackInvokedCallback フラグを使用することで、アクティビティ レベルで予測型システム アニメーションを無効にできます。この動作により、大規模なマルチアクティビティ アプリを予測型「戻る」ジェスチャーに移行しやすくなります。

次のコードは、MainActivity からホームに戻るシステム アニメーションを有効にするように enableOnBackInvokedCallback を設定する例を示しています。

<manifest ...>
    <application . . .

        android:enableOnBackInvokedCallback="false">

        <activity
            android:name=".MainActivity"
            android:enableOnBackInvokedCallback="true"
            ...
        </activity>
        <activity
            android:name=".SecondActivity"
            android:enableOnBackInvokedCallback="false"
            ...
        </activity>
    </application>
</manifest>

android:enableOnBackInvokedCallback フラグを使用する場合は、次の点にご注意ください。

  • android:enableOnBackInvokedCallback=false と設定すると、タグを設定した場所に応じて、アクティビティ レベルまたはアプリレベルで予測型「戻る」アニメーションがオフになります。また、システムに対して、OnBackInvokedCallback プラットフォーム API の呼び出しを無視するよう指示します。ただし、OnBackPressedCallback には下位互換性があり、Android 13 より前でサポートされていない onBackPressed API が呼び出されるため、OnBackPressedCallback の呼び出しは引き続き実行されます。
  • アプリレベルで enableOnBackInvokedCallback フラグを設定すると、アプリ内のすべてのアクティビティのデフォルト値が設定されます。アクティビティごとにデフォルトをオーバーライドするには、上記のコード例に示すように、アクティビティ レベルでフラグを設定します。

コールバックのガイドライン

サポートされているシステムの「戻る」コールバック(PredictiveBackHandler または BackHandler(Compose の場合)、OnBackPressedCallback、OnBackInvokedCallback)を使用する場合は、次のガイドラインに沿ってください。

各コールバックを有効または無効にする UI 状態を特定する

UI 状態は、UI を表すプロパティです。この手順の概要に沿って行うことをおすすめします。

  1. 各コールバックを有効または無効にする UI 状態を特定します。

  2. 観測可能なデータホルダーの型(StateFlow や Compose の状態など)を使用してその状態を定義し、状態が変化したときにコールバックを有効または無効にします。

アプリで以前に「戻る」ロジックを条件ステートメントと関連付けていた場合、「戻る」イベントがすでに発生した後で対応している可能性があります。新しいコールバックでは、このパターンを避けてください。可能であれば、コールバックを条件ステートメントの外側に移動して、代わりにコールバックを観測可能なデータホルダーの型に関連付けます。

UI ロジックにシステムの「戻る」コールバックを使用する

UI ロジックは、UI の表示方法を決定します。システムの「戻る」コールバックを使用して、ダイアログの表示やアニメーションの実行などの UI ロジックを実行します。

アプリが PRIORITY_DEFAULT または PRIORITY_OVERLAY で OnBackPressedCallback または OnBackInvokedCallback を有効にしている場合、予測型「戻る」アニメーションは実行されず、「戻る」イベントを処理する必要があります。ビジネス ロジックの実行やロギングのために、これらのコールバックを作成しないでください。

ユーザーがスワイプして戻ったときに、アプリでビジネス ロジックを実行したり、ログを記録したりする必要がある場合は、次の方法を使用します。

  • Compose の場合: Compose のデスティネーションに関連付けられた ViewModel の onCleared() コールバック内でログに記録します。これは、Compose のデスティネーションがバックスタックからポップされて破棄されたことを知るための最適なシグナルです。
  • Android 16 以降: PRIORITY_SYSTEM_NAVIGATION_OBSERVER で OnBackInvokedCallback を使用します。これにより、戻るイベントを消費しないオブザーバー コールバックが作成されます。たとえば、ユーザーがルート アクティビティから戻るスワイプを行った(アプリを終了した)ときに、このコールバックを登録して、戻るイベントをログに記録したり、ビジネス ロジックを実行したりしながら、ホームに戻るアニメーションを再生できます。
  • ビューベースのアプリの場合: 戻るイベントを消費するのではなく、ライフサイクルまたはバックスタックのコールバック内でログを記録します。
    • アクティビティの遷移については、Activity.onDestroy() 内で isFinishing が true であるかどうかを確認します。
    • フラグメント遷移の場合は、フラグメントのビュー ライフサイクル onDestroy() 内で isRemoving が true であるかどうかを確認するか、FragmentManager.OnBackStackChangedListener(onBackStackChangeStarted / onBackStackChangeCommitted)を使用します。

役割が 1 つのみのコールバックを作成する

ディスパッチャには複数のコールバックを追加できます。コールバックはスタックに追加され、最後に追加された有効なコールバックが、「戻る」操作ごとに 1 つのコールバックで次の「戻る」操作を処理します。

コールバックに単一の責任がある場合、そのコールバックの有効状態を管理する方が簡単です。次に例を示します。

Compose のスタック内のコールバックの順序。
図 2. Compose のコールバック スタック図。

図 2 は、スタックに複数のコールバックを配置し、それぞれが 1 つの処理を担当する方法を示しています。Compose では、コールバックは最も内側のコンポーザブルから最も外側のコンポーザブルまで評価され、コールバックは、スタック内でその前にあるコールバックが無効になっている場合にのみ実行されます。

  • 「本当に...」PredictiveBackHandler は、ユーザーがフォームにデータを入力すると有効になり、それ以外の場合は無効になります。有効にすると、戻る操作をインターセプトして、確認ダイアログまたはカスタムのアプリ内アニメーションを表示します。
  • 前のコールバックが無効になっている場合、画面レベルの BackHandler が実行されます。この例では、無効になっています。
  • NavHost コールバックは、前のカスタム コールバックが無効になっている場合に、バックスタックからデスティネーションをポップする「戻る」ナビゲーションを処理します。
  • 最後に、前のコールバックがすべて無効になっている場合、システムが「戻る」ジェスチャーを処理します。バックスタックがルート デスティネーションにある場合、システムは「ホームに戻る」、アクティビティ間、タスク間などのシステムレベルのアニメーションをトリガーします。

同じスタック動作がビューベースのアプリにも適用されます。最後に追加された有効な OnBackPressedCallback が優先され、FragmentManager にフォールバックし、最終的にシステムの「戻る」処理にフォールバックします。

予測型「戻る」ジェスチャーのアニメーションをテストする

Android 15 以降では、予測型「戻る」ナビゲーションをサポートするアプリで、ホームに戻る、タスク間、アクティビティ間などのシステム アニメーションがデフォルトで有効になります。開発者向けオプションではなくなりました。

Android 13 または Android 14 を搭載したデバイスでは、開発者向けオプションを有効にして、図 1 のようなホームに戻るアニメーションをテストできます。

  1. デバイスで、[設定] > [システム] > [開発者向けオプション] に移動します。

  2. [予測型「戻る」アニメーション] を選択します。

  3. 更新したアプリを起動し、「戻る」ジェスチャーを使用して実際の動作を確認します。