ใช้ตรรกะหรือ Wrapper กับปลายทาง

คุณสามารถระบุข้อมูลเพิ่มเติมหรือใช้ตรรกะเดียวกันกับ ปลายทางได้โดยใช้คลาส NavEntryDecorator คลาสนี้จะห่อหุ้มแต่ละ NavEntryใน Back Stack ด้วยฟังก์ชันที่ใช้ร่วมกันได้ กล่าวอีกนัยหนึ่งคือ ตกแต่งเนื้อหาของรายการ

สร้างตัวตกแต่งที่กำหนดเอง

หากต้องการสร้าง Decorator ให้ขยายคลาส NavEntryDecorator แล้วแทนที่เมธอดต่อไปนี้

  • decorate - Composable Lambda ที่เรียกใช้สำหรับแต่ละ NavEntry ใน Back Stack โดยจะรับ NavEntry เป็นพารามิเตอร์ ซึ่งช่วยให้คุณสร้างออบเจ็กต์สถานะที่เชื่อมโยงกับ contentKey ของรายการได้ คุณสามารถ ใช้ CompositionLocalProvider เพื่อระบุการอ้างอิงไปยังเนื้อหาของรายการ นอกจากนี้ คุณยังครอบเนื้อหาด้วยฟังก์ชันที่ใช้ร่วมกันได้ หรือทริกเกอร์ ผลข้างเคียงได้ด้วย คุณควรเรียกใช้ entry.Content() ภายในเมธอดนี้เสมอ
  • onPop - การเรียกกลับที่เรียกใช้เมื่อนำ NavEntry ออกจาก สแต็กย้อนกลับและออกจากคอมโพสิต โดยจะได้รับ contentKey ของ รายการที่นำออก ใช้ contentKey เพื่อระบุและล้างสถานะที่เชื่อมโยงกับรายการนั้น

ตัวอย่างต่อไปนี้ขยายคลาส NavEntryDecorator เพื่อสร้าง Decorator ที่กำหนดเอง

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

หากตัวตกแต่งต้องเข้าถึงสถานะ ให้สร้างฟังก์ชันที่ประกอบกันได้ซึ่งสร้างสถานะดังกล่าว แล้วใช้ฟังก์ชันนั้นเพื่อสร้างตัวตกแต่ง ดูตัวอย่าง การติดตั้งใช้งานได้ที่ซอร์สโค้ดของ rememberSaveableStateHolderNavEntryDecorator ซึ่งจะสร้าง สถานะ - SaveableStateHolder - และใช้เพื่อสร้างตัวตกแต่ง

ตกแต่ง Back Stack

เมื่อสร้าง NavEntryDecorator แล้ว ให้ตกแต่งรายการใน สแต็กย้อนกลับด้วยวิธีใดวิธีหนึ่งต่อไปนี้

  • ใช้ rememberDecoratedNavEntries ฟังก์ชันนี้มีประโยชน์เมื่อคุณมี Back Stack หลายรายการ ซึ่งแต่ละรายการมีชุด Decorator ของตัวเอง (ดูรายละเอียดเพิ่มเติมได้ที่สูตรโค้ดนี้) ฟังก์ชันจะแสดงรายการNavEntryที่ตกแต่งแล้ว ซึ่งคุณใช้กับ NavDisplay ได้
  • ระบุผู้ตกแต่งโดยตรงไปยัง NavDisplay โดยใช้พารามิเตอร์ entryDecorators NavDisplay จะเรียกใช้ rememberDecoratedNavEntries เบื้องหลัง และแสดงรายการที่ตกแต่งแล้ว

รวมเครื่องตกแต่งเริ่มต้น

Navigation 3 มี Decorator เริ่มต้นชื่อ SaveableStateHolderNavEntryDecorator ซึ่งช่วยให้NavEntryสามารถคงสถานะไว้ได้ แม้จะมีการเปลี่ยนแปลงการกำหนดค่าและกระบวนการสิ้นสุดลง โดยจะห่อหุ้มNavEntryเนื้อหาด้วยSaveableStateProvider ซึ่งจะช่วยให้การเรียกใช้ rememberSaveable ภายในเนื้อหา NavEntry ทำงานได้อย่างถูกต้อง

เว้นแต่ว่า Decorator ของคุณจะระบุ SaveableStateProvider คุณควร ใส่ SaveableStateHolderNavEntryDecorator เป็น Decorator แรกใน รายการ Decorator ที่ระบุ สร้างขึ้นโดยใช้ rememberSaveableStateHolderNavEntryDecorator

เช่น

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

กรณีที่ควรใช้ Decorator

ใช้ Decorator เพื่อทำสิ่งต่อไปนี้

  • สร้างการอ้างอิงสำหรับทุก NavEntry ใน Back Stack เช่น ViewModelStoreNavEntryDecorator จะสร้าง ViewModelStore สำหรับทุกๆ NavEntry
  • กำหนดขอบเขตออบเจ็กต์ไปยัง NavEntry หลายรายการ เช่น หากต้องการแชร์ ViewModel ระหว่างรายการหลายรายการ
  • ดำเนินการเดียวกันกับ NavEntry หลายรายการ เช่น เพื่อดำเนินการบันทึก การแก้ไขข้อบกพร่อง หรือการติดตามสำหรับแต่ละรายการ
  • ห่อหุ้ม NavEntry ด้วยฟังก์ชันที่ประกอบกันได้เดียวกัน
  • ล้างสถานะที่เชื่อมโยงกับ NavEntry เช่น เมื่อนำรายการออกจาก สแต็กย้อนกลับ ViewModelStoreNavEntryDecorator จะล้าง ViewModelStore ที่เชื่อมโยง

อย่าใช้ Decorator เพื่อทำสิ่งต่อไปนี้

  • ส่งการอ้างอิงไปยัง NavEntry รายการเดียว
  • ระบุการอ้างอิงที่มีขอบเขตกว้างกว่า Back Stack

ในทั้ง 2 กรณีนี้ ให้ส่งการอ้างอิงโดยตรงเมื่อสร้าง NavEntry แทน

ดูตัวอย่างโค้ดเพิ่มเติมได้ที่ NavEntryDecorator