บันทึกและจัดการสถานะการนําทาง

ส่วนต่อไปนี้อธิบายกลยุทธ์ในการบันทึกกองซ้อนที่ซ้อนกันอยู่และการจัดเก็บสถานะที่เชื่อมโยงกับรายการในกองซ้อนที่ซ้อนกันอยู่

บันทึกกองซ้อนที่ซ้อนกัน

การตรวจสอบว่าสถานะการนําทางของแอปยังคงอยู่ตลอดเหตุการณ์ต่างๆ ในวงจร ซึ่งรวมถึงการเปลี่ยนแปลงการกําหนดค่าและการหยุดทํางานของกระบวนการ เป็นสิ่งที่สําคัญอย่างยิ่งต่อประสบการณ์การใช้งานที่ดีของผู้ใช้ ใน 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 ให้ทําตามขั้นตอนต่อไปนี้

  1. เพิ่มการพึ่งพา androidx.lifecycle:lifecycle-viewmodel-navigation3 ลงในไฟล์ app/build.gradle.kts
  2. เพิ่ม rememberSavedStateNavEntryDecorator() ลงในรายการ entryDecorators เมื่อสร้าง NavDisplay
  3. เพิ่มตัวตกแต่งอื่นๆ ลงใน 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 { },
)