Navigation Compose API ช่วยให้คุณไปยังส่วนต่างๆ ระหว่าง Composable ในแอป Compose ได้ ขณะเดียวกันก็ใช้ประโยชน์จากคอมโพเนนต์ Jetpack Navigation's โครงสร้างพื้นฐาน และฟีเจอร์
หน้านี้อธิบายวิธีย้ายข้อมูลจาก Jetpack Navigation ที่อิงตาม Fragment ไปยัง Navigation Compose ซึ่งเป็นส่วนหนึ่งของการย้ายข้อมูล UI ที่อิงตาม View ไปยัง Jetpack Compose ที่มีขนาดใหญ่ขึ้น
ข้อกำหนดเบื้องต้นสำหรับการย้ายข้อมูล
คุณสามารถย้ายข้อมูลไปยัง Navigation Compose ได้เมื่อ แทนที่ Fragment ทั้งหมดด้วย Composable ของหน้าจอที่เกี่ยวข้องได้ Composable ของหน้าจออาจมี เนื้อหาทั้ง Compose และ View แต่ปลายทางการนำทางทั้งหมดต้องเป็น Composable เพื่อให้การย้ายข้อมูล Navigation Compose เป็นไปได้ จนกว่าจะถึงตอนนั้น คุณควรใช้คอมโพเนนต์การนำทางที่อิงตาม Fragment ในฐานของโค้ด View และ Compose ที่ทำงานร่วมกันต่อไป ดูข้อมูลเพิ่มเติมได้ในเอกสารประกอบการทำงานร่วมกันของการนำทาง
ขั้นตอนการย้ายข้อมูล
ไม่ว่าคุณจะใช้กลยุทธ์การย้ายข้อมูลที่แนะนำหรือใช้วิธีอื่น คุณจะไปถึงจุดที่ปลายทางการนำทางทั้งหมดเป็น Composable ของหน้าจอ โดย Fragment จะทำหน้าที่เป็นเพียงคอนเทนเนอร์ Composable ในขั้นตอนนี้ คุณสามารถย้ายข้อมูลไปยัง Navigation Compose ได้
หากแอปของคุณใช้รูปแบบการออกแบบ UDF และ คู่มือ สถาปัตยกรรมของเราอยู่แล้ว การย้ายข้อมูลไปยัง Jetpack Compose และ Navigation Compose ไม่ควรต้องมีการปรับโครงสร้างเลเยอร์อื่นๆ ของแอปครั้งใหญ่ นอกเหนือจากเลเยอร์ UI
หากต้องการย้ายข้อมูลไปยัง Navigation Compose ให้ทำตามขั้นตอนต่อไปนี้
- เพิ่มทรัพซีร์ส Dependency ของ Navigation Compose ลงในแอป
สร้าง Composable
App-levelแล้วเพิ่มลงในActivityเป็นจุดแรกเข้าของ Compose โดยแทนที่การตั้งค่าเลย์เอาต์ View ดังนี้class SampleActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // setContentView<ActivitySampleBinding>(this, R.layout.activity_sample) setContent { SampleApp(/* ... */) } } }
สร้างประเภทสำหรับปลายทางการนำทางแต่ละรายการ ใช้
data objectสำหรับ ปลายทางที่ไม่ต้องใช้ข้อมูล และdata classหรือclassสำหรับ ปลายทางที่ต้องใช้ข้อมูล@Serializable data object First @Serializable data class Second(val id: String) @Serializable data object Third
ตั้งค่า
NavControllerในตำแหน่งที่ Composable ทั้งหมดที่ต้อง อ้างอิงเข้าถึงได้ (โดยปกติจะอยู่ใน ComposableApp) วิธีนี้เป็นไปตามหลักการของการยกสถานะขึ้น และช่วยให้คุณใช้NavControllerเป็นแหล่งข้อมูลที่ถูกต้องเพียงแหล่งเดียวสำหรับการไปยังส่วนต่างๆ ระหว่างหน้าจอ Composable และการรักษา Back Stack@Composable fun SampleApp() { val navController = rememberNavController() // ... }
สร้าง
NavHostของแอปภายใน ComposableAppแล้วส่งnavController@Composable fun SampleApp() { val navController = rememberNavController() SampleNavHost(navController = navController) } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { // ... } }
เพิ่มปลายทาง
composableเพื่อสร้างกราฟการนำทาง หากย้ายข้อมูลแต่ละหน้าจอไปยัง Compose ไว้ก่อนหน้านี้ ขั้นตอนนี้จะประกอบด้วยการแยก Composable ของหน้าจอเหล่านี้จาก Fragment ไปยังปลายทางcomposableเท่านั้นclass FirstFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { return ComposeView(requireContext()).apply { setContent { // FirstScreen(...) EXTRACT FROM HERE } } } } @Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen(/* ... */) // EXTRACT TO HERE } composable<Second> { SecondScreen(/* ... */) } // ... } }
หากคุณทำตามคำแนะนำเกี่ยวกับ การออกแบบสถาปัตยกรรม UI ของ Compose, โดยเฉพาะวิธีส่ง
ViewModels และเหตุการณ์การนำทางไปยัง Composable ขั้นตอนถัดไปคือการเปลี่ยนวิธีที่คุณระบุViewModelให้กับ Composable ของหน้าจอแต่ละรายการ คุณมักจะใช้การแทรก Hilt และจุดผสานรวม กับ Compose และการนำทางผ่านhiltViewModelได้@Composable fun FirstScreen( // viewModel: FirstViewModel = viewModel(), viewModel: FirstViewModel = hiltViewModel(), onButtonClick: () -> Unit = {}, ) { // ... }
แทนที่การเรียกการนำทาง
findNavController()ทั้งหมดด้วยการเรียกnavControllerแล้วส่งการเรียกเหล่านี้เป็นเหตุการณ์การนำทางไปยังหน้าจอ Composable แต่ละรายการ แทนที่จะส่งnavControllerทั้งหมด วิธีนี้เป็นไปตามแนวทางปฏิบัติแนะนำ ในการแสดงเหตุการณ์จากฟังก์ชัน Composable ให้ผู้เรียก และ เก็บnavControllerไว้เป็นแหล่งข้อมูลที่ถูกต้องเพียงแหล่งเดียวคุณสามารถส่งข้อมูลไปยังปลายทางได้โดยการสร้างอินสแตนซ์ของคลาสเส้นทางที่กำหนดไว้สำหรับปลายทางนั้น จากนั้นคุณจะดึงข้อมูลได้โดยตรง จากรายการ Back Stack ที่ปลายทาง หรือจาก
ViewModelโดยใช้SavedStateHandle.toRoute()@Composable fun SampleNavHost( navController: NavHostController ) { NavHost(navController = navController, startDestination = First) { composable<First> { FirstScreen( onButtonClick = { // findNavController().navigate(firstScreenToSecondScreenAction) navController.navigate(Second(id = "ABC")) } ) } composable<Second> { backStackEntry -> val secondRoute = backStackEntry.toRoute<Second>() SecondScreen( id = secondRoute.id, onIconClick = { // findNavController().navigate(secondScreenToThirdScreenAction) navController.navigate(Third) } ) } // ... } }
นำ Fragment, เลย์เอาต์ XML ที่เกี่ยวข้อง, การนำทางและทรัพยากรอื่นๆ ที่ไม่จำเป็น รวมถึงทรัพยากร Dependency ของ Fragment และ Jetpack Navigation ที่ล้าสมัยออกทั้งหมด
คุณสามารถดูขั้นตอนเดียวกันนี้พร้อมรายละเอียดเพิ่มเติมที่เกี่ยวข้องกับ Navigation Compose ได้ใน เอกสารประกอบการตั้งค่า
กรณีการใช้งานทั่วไป
ไม่ว่าคุณจะใช้คอมโพเนนต์การนำทางใด หลักการนำทางเดียวกันนี้ จะยังคงใช้ได้
กรณีการใช้งานทั่วไปเมื่อย้ายข้อมูลมีดังนี้
- ไปยังส่วนต่างๆ ของ Composable
- ไปยังส่วนต่างๆ ด้วยอาร์กิวเมนต์
- Deep Link
- การนำทางแบบซ้อน
- การผสานรวมกับแถบการนำทางด้านล่าง
- การผสานรวมกับคอมโพเนนต์การนำทางที่กำหนดเอง
ดูข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับกรณีการใช้งานเหล่านี้ได้ที่ การนำทางด้วย Compose
ดึงข้อมูลที่ซับซ้อนเมื่อไปยังส่วนต่างๆ
เราขอแนะนำอย่างยิ่งไม่ให้ส่งออบเจ็กต์ข้อมูลที่ซับซ้อนเมื่อไปยังส่วนต่างๆ แต่ให้ส่งข้อมูลที่จำเป็นขั้นต่ำ เช่น ตัวระบุที่ไม่ซ้ำกันหรือรหัสรูปแบบอื่นๆ เป็นอาร์กิวเมนต์เมื่อดำเนินการการนำทาง คุณควร เก็บออบเจ็กต์ที่ซับซ้อนเป็นข้อมูลในแหล่งข้อมูลที่ถูกต้องเพียงแหล่งเดียว เช่น เลเยอร์ ข้อมูล ดูข้อมูลเพิ่มเติมได้ที่การดึงข้อมูลที่ซับซ้อนเมื่อ ไปยังส่วนต่างๆ
หาก Fragment ของคุณส่งออบเจ็กต์ที่ซับซ้อนเป็นอาร์กิวเมนต์ ให้พิจารณาปรับโครงสร้างโค้ดก่อนในลักษณะที่อนุญาตให้จัดเก็บและดึงออบเจ็กต์เหล่านี้จากชั้นข้อมูลได้ ดูตัวอย่างได้ในที่เก็บ Now in Android สำหรับ
ข้อจำกัด
ส่วนนี้อธิบายข้อจำกัดปัจจุบันของ Navigation Compose
การย้ายข้อมูลไปยัง Navigation Compose ทีละขั้น
ปัจจุบันคุณไม่สามารถใช้ Navigation Compose ขณะที่ยังใช้ Fragment เป็นปลายทางในโค้ดได้ หากต้องการเริ่มใช้ Navigation Compose ปลายทางทั้งหมดต้องเป็น Composable คุณสามารถติดตามคำขอฟีเจอร์นี้ได้ใน Issue Tracker
ภาพเคลื่อนไหวการเปลี่ยน
ตั้งแต่ Navigation 2.7.0-alpha01 เป็นต้นไป ระบบจะรองรับการตั้งค่าการเปลี่ยนที่กำหนดเอง
ซึ่งก่อนหน้านี้ตั้งค่าได้จาก AnimatedNavHost ใน NavHost โดยตรง อ่านข้อมูลเพิ่มเติมได้ในบันทึกประจำรุ่น
ดูข้อมูลเพิ่มเติม
ดูข้อมูลเพิ่มเติมเกี่ยวกับการย้ายข้อมูลไปยัง Navigation Compose ได้จากแหล่งข้อมูลต่อไปนี้
- Codelab Navigation Compose: เรียนรู้พื้นฐานของ Navigation Compose ด้วย Codelab เชิงปฏิบัติ
- ที่เก็บ Now in Android: แอป Android ที่ทำงานได้อย่างสมบูรณ์ ซึ่งสร้างขึ้นด้วย Kotlin และ Jetpack Compose ทั้งหมด โดยเป็นไปตามแนวทางปฏิบัติแนะนำด้านการออกแบบ และการพัฒนา Android รวมถึงมี Navigation Compose
- การย้ายข้อมูล Sunflower ไปยัง Jetpack Compose: บล็อกโพสต์ที่ บันทึกการเดินทางของการย้ายข้อมูลแอปตัวอย่าง Sunflower จาก Views ไปยัง Compose ซึ่งรวมถึงการย้ายข้อมูลไปยัง Navigation Compose ด้วย
- Jetnews สำหรับทุกหน้าจอ: บล็อกโพสต์ที่บันทึก การปรับโครงสร้างและการย้ายข้อมูลแอปตัวอย่าง Jetnews เพื่อรองรับทุกหน้าจอด้วย Jetpack Compose และ Navigation Compose
แนะนำสำหรับคุณ
- หมายเหตุ: ข้อความลิงก์จะแสดงเมื่อ JavaScript ปิดอยู่
- การนำทางด้วย Compose
- Compose และไลบรารีอื่นๆ
- ปัจจัยอื่นๆ ที่ควรพิจารณา