การไปยังส่วนต่างๆ อธิบายวิธีที่ผู้ใช้ย้ายไปรอบๆ ในแอป ผู้ใช้โต้ตอบกับองค์ประกอบ UI โดยมักจะแตะหรือคลิกองค์ประกอบเหล่านั้น และแอปจะตอบสนองด้วยการแสดงเนื้อหาใหม่ หากผู้ใช้ต้องการกลับไปดูเนื้อหาก่อนหน้า ก็จะใช้ท่าทางสัมผัสเพื่อย้อนกลับหรือแตะปุ่มย้อนกลับ
การสร้างแบบจำลองสถานะการไปยังส่วนต่างๆ
วิธีที่สะดวกในการสร้างแบบจำลองลักษณะการทำงานนี้คือการใช้สแต็กเนื้อหา เมื่อผู้ใช้ไปยังส่วนต่างๆ ไปข้างหน้า เพื่อดูเนื้อหาใหม่ ระบบจะวางเนื้อหาดังกล่าวไว้ที่ด้านบนของสแต็ก เมื่อผู้ใช้ กลับ จากเนื้อหานั้น ระบบจะนำเนื้อหาดังกล่าวออกจากสแต็กและแสดงเนื้อหาก่อนหน้า ในแง่ของการนำทาง โดยปกติแล้วสแต็กนี้จะเรียกว่าBack Stack เนื่องจากแสดงเนื้อหาที่ผู้ใช้ สามารถย้อนกลับไปดูได้
สร้าง Back Stack
ใน การนำทาง 3 Back Stack จะไม่มีเนื้อหาจริง แต่จะมี การอ้างอิงถึงเนื้อหา ซึ่งเรียกว่า คีย์ คีย์เป็นประเภทใดก็ได้ แต่มักจะเป็นคลาสข้อมูลที่เรียบง่ายและทำให้เป็นอนุกรมได้ การใช้การอ้างอิงแทนเนื้อหามีประโยชน์ดังนี้
- การไปยังส่วนต่างๆ ทำได้ง่ายโดยการวางคีย์ลงใน Back Stack
- ตราบใดที่คีย์ทำให้เป็นอนุกรมได้ ระบบจะบันทึกสแต็กย้อนกลับลงในพื้นที่เก็บข้อมูลถาวรได้ ซึ่งจะช่วยให้สแต็กย้อนกลับยังคงอยู่ได้แม้จะมีการเปลี่ยนแปลงการกำหนดค่าและการสิ้นสุดกระบวนการ ซึ่งเป็นสิ่งสำคัญเนื่องจากผู้ใช้คาดหวังว่าจะออกจากแอป กลับมาใช้แอปอีกครั้งในภายหลัง และดำเนินการต่อจากจุดที่ค้างไว้โดยแสดงเนื้อหาเดิม ดูข้อมูลเพิ่มเติมได้ที่ บันทึก Back Stack
แนวคิดหลักใน Navigation 3 API คือคุณเป็นเจ้าของ Back Stack ไลบรารีจะดำเนินการดังนี้
- คาดหวังว่า Back Stack ของคุณจะเป็น
List<T>ที่สำรองข้อมูลด้วยสถานะสแนปชอต โดยTคือประเภทkeysของ Back Stack คุณสามารถใช้Anyหรือระบุคีย์ที่มีการพิมพ์ที่เข้มงวดมากขึ้น เมื่อเห็นคำว่า "พุช" หรือ "นำออก" การใช้งานเบื้องหลังคือการเพิ่มหรือนำรายการออกจากท้ายรายการ - สังเกต Back Stack และแสดงสถานะใน UI โดยใช้
NavDisplay
ตัวอย่างต่อไปนี้แสดงวิธีสร้างคีย์และ Back Stack รวมถึงแก้ไข Back Stack เพื่อตอบสนองต่อเหตุการณ์การนำทางของผู้ใช้
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
แปลงคีย์เป็นเนื้อหา
Navigation 3 สร้างแบบจำลองเนื้อหาโดยใช้ NavEntry ซึ่งเป็นคลาส
ที่มีฟังก์ชันที่ประกอบกันได้ โดยแสดงถึง ปลายทาง - เนื้อหาชิ้นเดียว
ที่ผู้ใช้สามารถไปยังส่วนต่างๆ ไปข้างหน้า และ ย้อนกลับ ได้
NavEntry ยังมีข้อมูลเมตา ซึ่งเป็นข้อมูลเกี่ยวกับเนื้อหาได้ด้วย ออบเจ็กต์คอนเทนเนอร์ เช่น NavDisplay สามารถอ่านข้อมูลเมตานี้เพื่อช่วยในการตัดสินใจว่าจะแสดงเนื้อหาของ NavEntry อย่างไร ตัวอย่างเช่น ข้อมูลเมตาสามารถใช้เพื่อลบล้างภาพเคลื่อนไหวเริ่มต้นสำหรับ NavEntry ที่เฉพาะเจาะจงได้ `ข้อมูลเมตา` ของ NavEntry
metadata เป็นแผนที่ของคีย์ String กับค่า Any ซึ่งช่วยให้จัดเก็บข้อมูลได้อย่างหลากหลาย
หากต้องการแปลง key เป็น NavEntry ให้สร้างผู้ให้บริการรายการ ซึ่งเป็น
ฟังก์ชันที่รับ key และแสดงผล NavEntry สำหรับ key นั้น โดยปกติแล้วจะกำหนดเป็นพารามิเตอร์แลมบ์ดาเมื่อสร้าง NavDisplay
คุณสร้างฟังก์ชันผู้ให้บริการรายการได้ 2 วิธี ได้แก่ สร้างฟังก์ชันแลมบ์ดา
โดยตรง หรือใช้ entryProvider DSL
สร้างฟังก์ชันผู้ให้บริการรายการโดยตรง
โดยปกติแล้วคุณจะสร้างฟังก์ชันผู้ให้บริการรายการโดยใช้คำสั่ง when ที่มีสาขาสำหรับคีย์แต่ละรายการ
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
ใช้ DSL entryProvider
DSL entryProvider สามารถลดความซับซ้อนของฟังก์ชันแลมบ์ดาได้โดยไม่จำเป็นต้องทดสอบกับคีย์แต่ละประเภทและสร้าง NavEntry สำหรับคีย์แต่ละประเภท
ให้ใช้ฟังก์ชันตัวสร้าง entryProvider สำหรับการดำเนินการนี้ นอกจากนี้ยังมีลักษณะการทำงานสำรองเริ่มต้น (แสดงข้อผิดพลาด) หากไม่พบคีย์
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
โปรดทราบสิ่งต่อไปนี้จากข้อมูลโค้ด
entryใช้เพื่อกำหนดNavEntryที่มีประเภทและเนื้อหาที่ประกอบกันได้ที่ระบุentryรับพารามิเตอร์metadataเพื่อตั้งค่าNavEntry.metadata
แสดง Back Stack
Back Stack แสดงถึงสถานะการนำทางของแอป เมื่อใดก็ตามที่ Back Stack เปลี่ยนแปลง UI ของแอปควรแสดงสถานะ Back Stack ใหม่ ใน Navigation 3 NavDisplay จะสังเกต Back Stack และอัปเดต UI ตามนั้น สร้างโดยใช้พารามิเตอร์ต่อไปนี้
- สแต็กย้อนกลับ - ควรมีประเภทเป็น
SnapshotStateList<T>โดยTคือ ประเภทคีย์ของสแต็กย้อนกลับ ซึ่งเป็นListที่สังเกตได้เพื่อให้ทริกเกอร์การจัดองค์ประกอบใหม่ของNavDisplayเมื่อมีการเปลี่ยนแปลง entryProviderเพื่อแปลงคีย์ใน Back Stack เป็นออบเจ็กต์NavEntry- ระบุแลมบ์ดาสำหรับพารามิเตอร์
onBackก็ได้ ระบบจะเรียกใช้พารามิเตอร์นี้เมื่อผู้ใช้ทริกเกอร์เหตุการณ์ย้อนกลับ
ตัวอย่างต่อไปนี้แสดงวิธีสร้าง NavDisplay
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
โดยค่าเริ่มต้น NavDisplay จะแสดง NavEntry ที่อยู่ด้านบนสุดใน Back Stack ในเลย์เอาต์แบบบานหน้าต่างเดียว การบันทึกต่อไปนี้แสดงแอปนี้ที่กำลังทำงาน
NavDisplay ที่มีปลายทางสอง
แห่งวงจรของปลายทาง
NavDisplay ใช้ ที่กำหนดเอง LifecycleOwners เพื่อจำกัดสถานะวงจรของ
NavEntry โดยอิงตามข้อจำกัดระดับฉากและข้อจำกัดระดับรายการ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวงจรใน Compose ได้ที่ วงจรใน Jetpack Compose
ข้อจำกัดวงจรระดับฉาก
NavDisplay จัดการวงจรของ Scene ที่ใช้งานอยู่ ข้อจำกัดระดับฉากจะกำหนดไว้ดังนี้
สำหรับฉากที่ไม่ใช่การซ้อนทับ
RESUMED: อนุญาตเฉพาะเมื่อการเปลี่ยนฉากเสร็จสมบูรณ์แล้วและไม่มีฉากการซ้อนทับที่ใช้งานอยู่แสดงอยู่ด้านบนSTARTED: จำกัดไว้ที่STARTEDขณะที่ฉากกำลังเปลี่ยน เช่น เมื่อไปยังส่วนต่างๆ ไปข้างหน้าหรือย้อนกลับ หรือเมื่อฉากถูกซ้อนทับ
สำหรับฉากการซ้อนทับ เช่น กล่องโต้ตอบหรือ Bottom Sheet
RESUMED: อนุญาตเฉพาะฉากการซ้อนทับที่ใช้งานอยู่และอยู่ด้านบนสุดSTARTED: จำกัดไว้ที่STARTEDสำหรับฉากการซ้อนทับที่อยู่ด้านล่างซึ่งถูกซ้อนทับด้วยฉากการซ้อนทับใหม่กว่า
สถานะวงจรระดับรายการ
ไลบรารีจะจัดการสถานะวงจรสูงสุดของ NavEntry แต่ละรายการโดยอิงตามการมีอยู่ของรายการใน Back Stack ดังนี้
RESUMED: หากรายการอยู่ในสแต็กย้อนกลับปัจจุบัน ระบบจะอนุญาตให้วงจรของรายการไปถึงRESUMED(ขึ้นอยู่กับข้อจำกัดระดับฉาก)CREATED: หากรายการไม่อยู่ใน Back Stack, แล้ว เช่น เมื่อนำรายการออกแต่ยังคงแสดงบนหน้าจอขณะที่กำลังแสดงภาพเคลื่อนไหวเพื่อนำออก ไลบรารีจะจำกัดวงจรของรายการไว้ที่CREATEDอย่างเข้มงวด ข้อจำกัดนี้ช่วยให้รายการที่อยู่เบื้องหลังหรือรายการที่กำลังออกจากระบบหยุดการทำงานที่ใช้งานอยู่ เช่น การรวบรวมโฟลว์หรือการเปิดใช้โครูทีนที่ผูกกับสถานะRESUMEDหรือSTARTEDขณะที่รายการกำลังทำการเปลี่ยนออก
วิธีรวมสถานะวงจร
ตัวอย่างเช่น ระบบจะกำหนดสถานะวงจรสุดท้ายของ NavEntry ดังนี้
| สถานการณ์ | ข้อจำกัดระดับฉาก | ข้อจำกัดระดับรายการ | ข้อจำกัดที่มีผล |
|---|---|---|---|
| รายการที่ใช้งานอยู่ หน้าจอที่เสร็จสมบูรณ์ (ไม่มีการเปลี่ยนหรือการซ้อนทับ) | RESUMED |
RESUMED |
RESUMED |
| รายการที่ใช้งานอยู่ ระหว่างการเปลี่ยน (การไปยังส่วนต่างๆ ไปยังหรือจาก) | STARTED |
RESUMED |
STARTED |
| รายการที่ใช้งานอยู่ ซึ่งถูกซ้อนทับ (เช่น กล่องโต้ตอบเปิดอยู่) | STARTED |
RESUMED |
STARTED |
| รายการที่นำออก กำลังแสดงภาพเคลื่อนไหวเพื่อนำออก | STARTED หรือ RESUMED |
CREATED |
CREATED |
สรุปข้อมูลทั้งหมด
แผนภาพต่อไปนี้แสดงวิธีที่ข้อมูลไหลเวียนระหว่างออบเจ็กต์ต่างๆ ใน Navigation 3
เหตุการณ์การนำทางจะเริ่มการเปลี่ยนแปลง ระบบจะเพิ่มหรือนำคีย์ออกจาก Back Stack เพื่อตอบสนองต่อการโต้ตอบของผู้ใช้
การเปลี่ยนแปลงสถานะ Back Stack จะทริกเกอร์การดึงข้อมูลเนื้อหา
NavDisplay(Composable ที่แสดง Back Stack) จะสังเกต Back Stack ในการกำหนดค่าเริ่มต้น ฟังก์ชันนี้จะแสดงรายการ Back Stack ที่อยู่ด้านบนสุดในเลย์เอาต์แบบบานหน้าต่างเดียว เมื่อคีย์ด้านบนสุดใน Back Stack เปลี่ยนแปลงNavDisplayจะใช้คีย์นี้เพื่อขอเนื้อหาที่เกี่ยวข้องจากผู้ให้บริการรายการผู้ให้บริการรายการจะให้เนื้อหา ผู้ให้บริการรายการเป็นฟังก์ชันที่แปลงคีย์เป็น
NavEntryเมื่อได้รับคีย์จากNavDisplayผู้ให้บริการรายการจะให้NavEntryที่เชื่อมโยง ซึ่งมีทั้งคีย์และเนื้อหาเนื้อหาจะแสดงขึ้น
NavDisplayจะได้รับNavEntryและแสดงเนื้อหา