以下各節將說明如何儲存返回堆疊,以及儲存與返回堆疊項目相關聯的狀態。
儲存返回堆疊
確保應用程式的導覽狀態在各種生命週期事件 (包括設定變更和程序終止) 中保持不變,是提供良好使用者體驗的關鍵。在 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 中
管理返回堆疊的另一種做法,是將其儲存在 ViewModel 中。
如要在使用 ViewModel 或任何其他自訂儲存空間時,透過程序終止作業保留資料,請採取下列做法:
- 確保金鑰可序列化:與
rememberNavBackStack相同,導覽鍵必須可序列化。 - 手動處理序列化和還原序列化作業:您必須負責將每個金鑰的序列化表示法手動儲存至永久儲存空間 (例如
SharedPreferences、資料庫或檔案),以便在應用程式進入背景或還原時使用。
範圍從 ViewModel 秒到 NavEntry 秒
ViewModels 可用於在設定變更 (例如螢幕旋轉) 時保留 UI 相關狀態。根據預設,ViewModels 的範圍會設為最接近的 ViewModelStoreOwner,通常是 Activity 或 Fragment。
不過,您可能想將 ViewModel 範圍限定在返回堆疊中的特定 NavEntry (即特定畫面或目的地),而不是整個 Activity。這樣可確保只有在特定 NavEntry 屬於返回堆疊時,才會保留 ViewModel 的狀態,並在 NavEntry 彈出時清除狀態。
androidx.lifecycle:lifecycle-viewmodel-navigation3 外掛程式庫提供 NavEntryDecorator,可簡化這項作業。這個裝飾器會為每個 NavEntry 提供 ViewModelStoreOwner。在 NavEntry 的內容中建立 ViewModel 時 (例如在 Compose 中使用 viewModel()),系統會自動將其範圍限定在返回堆疊中該特定 NavEntry 的鍵。也就是說,NavEntry 新增至返回堆疊時,系統會建立 ViewModel,移除時則會清除。
如要使用 NavEntryDecorator 將 ViewModel 範圍限定為 NavEntry,請按照下列步驟操作:
- 在
app/build.gradle.kts檔案中新增androidx.lifecycle:lifecycle-viewmodel-navigation3依附元件。 - 建構
NavDisplay時,請將rememberSaveableStateHolderNavEntryDecorator()新增至entryDecorators清單。 - 在
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 { }, )