บันทึกและจัดการสถานะการนําทาง
จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน
บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ
ส่วนต่อไปนี้อธิบายกลยุทธ์ในการบันทึกกองซ้อนที่ซ้อนกันอยู่และการจัดเก็บสถานะที่เชื่อมโยงกับรายการในกองซ้อนที่ซ้อนกันอยู่
บันทึกกองซ้อนที่ซ้อนกัน
การตรวจสอบว่าสถานะการนําทางของแอปยังคงอยู่ตลอดเหตุการณ์ต่างๆ ในวงจร ซึ่งรวมถึงการเปลี่ยนแปลงการกําหนดค่าและการหยุดทํางานของกระบวนการ เป็นสิ่งสําคัญอย่างยิ่งต่อประสบการณ์การใช้งานที่ดีของผู้ใช้ ใน Navigation 3 คุณเป็นเจ้าของกองซ้อนที่ย้อนกลับ ดังนั้นจึงไม่มีหลักเกณฑ์ที่เข้มงวดเกี่ยวกับวิธีสร้างหรือบันทึกกองซ้อนดังกล่าว อย่างไรก็ตาม การนำทาง 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
ที่อำนวยความสะดวกในเรื่องนี้ ตัวแปรตกแต่งนี้จะสร้าง ViewModelStoreOwner
สำหรับ NavEntry
แต่ละรายการ เมื่อคุณสร้าง ViewModel
ภายในเนื้อหาของ NavEntry
(เช่น ใช้ viewModel()
ในเครื่องมือเขียน) ระบบจะกําหนดขอบเขต ViewModel
นั้นโดยอัตโนมัติไปยังคีย์ของ NavEntry
นั้นในกองซ้อนด้านหลัง ซึ่งหมายความว่าViewModel
จะสร้างขึ้นเมื่อเพิ่ม NavEntry
ลงในกองซ้อนด้านหลัง และล้างออกเมื่อนำออก
หากต้องการใช้ NavEntryDecorator
เพื่อกําหนดขอบเขต ViewModel
ให้กับ NavEntry
ให้ทําตามขั้นตอนต่อไปนี้
- เพิ่มการพึ่งพา
androidx.lifecycle:lifecycle-viewmodel-navigation3
ลงในไฟล์ app/build.gradle.kts
- เพิ่ม
rememberSavedStateNavEntryDecorator()
ลงในรายการ entryDecorators
เมื่อสร้าง NavDisplay
- เพิ่มตัวตกแต่งอื่นๆ ลงใน
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 { },
)
ตัวอย่างเนื้อหาและโค้ดในหน้าเว็บนี้ขึ้นอยู่กับใบอนุญาตที่อธิบายไว้ในใบอนุญาตการใช้เนื้อหา Java และ OpenJDK เป็นเครื่องหมายการค้าหรือเครื่องหมายการค้าจดทะเบียนของ Oracle และ/หรือบริษัทในเครือ
อัปเดตล่าสุด 2025-07-27 UTC
[[["เข้าใจง่าย","easyToUnderstand","thumb-up"],["แก้ปัญหาของฉันได้","solvedMyProblem","thumb-up"],["อื่นๆ","otherUp","thumb-up"]],[["ไม่มีข้อมูลที่ฉันต้องการ","missingTheInformationINeed","thumb-down"],["ซับซ้อนเกินไป/มีหลายขั้นตอนมากเกินไป","tooComplicatedTooManySteps","thumb-down"],["ล้าสมัย","outOfDate","thumb-down"],["ปัญหาเกี่ยวกับการแปล","translationIssue","thumb-down"],["ตัวอย่าง/ปัญหาเกี่ยวกับโค้ด","samplesCodeIssue","thumb-down"],["อื่นๆ","otherDown","thumb-down"]],["อัปเดตล่าสุด 2025-07-27 UTC"],[],[],null,["# Save and manage navigation state\n\nThe following sections describe strategies for saving your back stack and\nstoring state associated with entries on your back stack.\n\nSave your back stack\n--------------------\n\nEnsuring your app's navigation state persists across various lifecycle events,\nincluding configuration changes and process death, is crucial for a good user\nexperience. In Navigation 3, you own your back stack, so there aren't strict\nguidelines on how you should create or save it. However, Navigation 3 does offer\na convenience method that provides you with a saveable back stack:\n[`rememberNavBackStack`](/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberNavBackStack(kotlin.Array)).\n\n### Use `rememberNavBackStack`\n\nThe `rememberNavBackStack` composable function is designed to create a back\nstack that persists across configuration changes and process death.\n\nFor `rememberNavBackStack` to function correctly, each key in your back stack\nmust adhere to specific requirements:\n\n- **Implement `NavKey` interface** : Every key in the back stack must implement the [`NavKey`](/reference/kotlin/androidx/navigation3/runtime/NavKey) interface. This acts as a marker interface that signals to the library that the key can be saved.\n- **Have the `@Serializable` annotation** : In addition to implementing `NavKey`, your key classes and objects must be marked with the `@Serializable` annotation.\n\nThe following snippet shows a correct implementation of `rememberNavBackStack`:\n\n\n```kotlin\n@Serializable\ndata object Home : NavKey\n\n@Composable\nfun NavBackStack() {\n val backStack = rememberNavBackStack(Home)\n}https://github.com/android/snippets/blob/26d364466ee1c03d658ba2f0905f7cc1a97afefa/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/savingstate/SavingStateSnippets.kt#L30-L36\n```\n\n\u003cbr /\u003e\n\n### Alternative: Storing in a `ViewModel`\n\nAnother approach to managing your back stack is to store it in a `ViewModel`.\nFor persistence through process death when using a `ViewModel` or any other\ncustom storage, you need to:\n\n- **Ensure your keys are serializable** : Just like with `rememberNavBackStack`, your navigation keys must be serializable.\n- **Handle serialization and deserialization manually** : You're responsible for manually saving the serialized representation of each key to, and deserializing it from, persistent storage (e.g., `SharedPreferences`, a database, or a file) when your app is going into the background or being restored.\n\nScoping `ViewModel`s to `NavEntry`s\n-----------------------------------\n\n`ViewModels` are used to retain UI-related state across configuration changes,\nsuch as screen rotations. By default, `ViewModels` are scoped to the nearest\n`ViewModelStoreOwner`, which is typically your `Activity` or `Fragment`.\n\nHowever, you might want to scope a `ViewModel` to a specific `NavEntry` (i.e., a\nspecific screen or destination) on the back stack, rather than the entire\n`Activity`. This ensures that the `ViewModel`'s state is retained only while\nthat particular `NavEntry` is part of the back stack, and is cleared when the\n`NavEntry` is popped.\n\nThe `androidx.lifecycle:lifecycle-viewmodel-navigation3` add-on library provides\na `NavEntryDecorator` that facilitates this. This decorator provides a\n`ViewModelStoreOwner` for each `NavEntry`. When you create a `ViewModel` inside a\n`NavEntry`'s content (e.g., using `viewModel()` in Compose), it is automatically\nscoped to that specific `NavEntry`'s key on the back stack. This means the\n`ViewModel` is created when the `NavEntry` is added to the back stack, and\ncleared when it's removed.\n\nTo use `NavEntryDecorator` for scoping `ViewModel`s to `NavEntry`s, follow these\nsteps:\n\n1. Add the `androidx.lifecycle:lifecycle-viewmodel-navigation3` dependency to your `app/build.gradle.kts` file.\n2. Add [`rememberSavedStateNavEntryDecorator()`](/reference/kotlin/androidx/navigation3/runtime/package-summary#rememberSavedStateNavEntryDecorator(androidx.compose.runtime.saveable.SaveableStateHolder)) to the list of `entryDecorators` when constructing a `NavDisplay`.\n3. Add other decorators into your `NavDisplay`.\n\n\n```kotlin\nNavDisplay(\n entryDecorators = listOf(\n // Add the default decorators for managing scenes and saving state\n rememberSceneSetupNavEntryDecorator(),\n rememberSavedStateNavEntryDecorator(),\n // Then add the view model store decorator\n rememberViewModelStoreNavEntryDecorator()\n ),\n backStack = backStack,\n entryProvider = entryProvider { },\n)https://github.com/android/snippets/blob/26d364466ee1c03d658ba2f0905f7cc1a97afefa/compose/snippets/src/main/java/com/example/compose/snippets/navigation3/savingstate/SavingStateSnippets.kt#L45-L55\n```\n\n\u003cbr /\u003e"]]