以下各節將說明儲存返回堆疊的策略,以及儲存與返回堆疊項目相關聯的狀態。
儲存返回堆疊
為提供良好的使用者體驗,請務必確保應用程式的導覽狀態在各種生命週期事件 (包括設定變更和程序終止) 中持續存在。在 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
。這樣可確保 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
時,將rememberSavedStateNavEntryDecorator()
新增至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 { }, )