以降のセクションでは、バックスタックを保存し、バックスタック内のエントリに関連付けられた状態を保存するための戦略について説明します。
バックスタックを保存する
優れたユーザー エクスペリエンスを実現するには、構成の変更やプロセスの終了など、さまざまなライフサイクル イベントでアプリのナビゲーション状態が保持されるようにすることが重要です。Navigation 3 では、バックスタックを所有するため、バックスタックの作成方法や保存方法に関する厳格なガイドラインはありません。ただし、Navigation 3 には、保存可能なバックスタック(rememberNavBackStack
)を提供する便利なメソッドがあります。
rememberNavBackStack
rememberNavBackStack
コンポーズ可能な関数は、構成の変更やプロセスの終了後も保持されるバックスタックを作成するように設計されています。
rememberNavBackStack
が正しく機能するには、バックスタック内の各キーが特定の要件を満たしている必要があります。
NavKey
インターフェースを実装する: バックスタック内のすべてのキーはNavKey
インターフェースを実装する必要があります。これは、キーを保存できることをライブラリに通知するマーカー インターフェースとして機能します。@Serializable
アノテーションがある:NavKey
を実装するだけでなく、鍵クラスとオブジェクトに@Serializable
アノテーションを付ける必要があります。
次のスニペットは、rememberNavBackStack
の正しい実装を示しています。
@Serializable data object Home : NavKey @Composable fun NavBackStack() { val backStack = rememberNavBackStack(Home) }
代替手段: ViewModel
に保存する
バックスタックを管理するもう 1 つの方法は、ViewModel
に保存することです。ViewModel
などのカスタム ストレージを使用してプロセスの終了後も永続化するには、次の操作を行う必要があります。
- キーがシリアル化可能であることを確認する:
rememberNavBackStack
と同様に、ナビゲーション キーはシリアル化可能である必要があります。 - シリアル化とシリアル化解除を手動で処理する: 各キーのシリアル化された表現を手動で永続ストレージ(
SharedPreferences
、データベース、ファイル)を保存します。
ViewModel
を NavEntry
にスコープ設定する
ViewModels
は、画面の回転などの構成変更後も UI 関連の状態を保持するために使用されます。デフォルトでは、ViewModels
は最も近い ViewModelStoreOwner
(通常は Activity
または Fragment
)にスコープされます。
ただし、ViewModel
のスコープを Activity
全体ではなく、バックスタック上の特定の NavEntry
(特定の画面またはデスティネーション)に設定することもできます。これにより、ViewModel
の状態は、その特定の NavEntry
がバックスタックの一部である間のみ保持され、NavEntry
がポップされるとクリアされます。
androidx.lifecycle:lifecycle-viewmodel-navigation3
アドオン ライブラリには、これを容易にする NavEntryDecorator
が用意されています。このデコレータは、NavEntry
ごとに ViewModelStoreOwner
を提供します。NavEntry
のコンテンツ内に ViewModel
を作成すると(Compose で viewModel()
を使用するなど)、バックスタック上の特定の NavEntry
のキーに自動的にスコープが設定されます。つまり、NavEntry
がバックスタックに追加されると ViewModel
が作成され、削除されると消去されます。
NavEntryDecorator
を使用して ViewModel
を NavEntry
にスコープ設定する手順は次のとおりです。
androidx.lifecycle:lifecycle-viewmodel-navigation3
依存関係をapp/build.gradle.kts
ファイルに追加します。NavDisplay
を作成するときに、entryDecorators
のリストにrememberSavedStateNavEntryDecorator()
を追加します。NavDisplay
に他のデコレーターを追加します。
NavDisplay( entryDecorators = listOf( // Add the default decorators for managing scenes and saving state rememberSceneSetupNavEntryDecorator(), rememberSavedStateNavEntryDecorator(), // Then add the view model store decorator rememberViewModelStoreNavEntryDecorator() ), backStack = backStack, entryProvider = entryProvider { }, )