คอมโพเนนต์การนำทางมีวิธีที่ตรงไปตรงมาและทั่วไปในการ ไปยังปลายทาง อินเทอร์เฟซนี้รองรับบริบทและเฟรมเวิร์ก UI ที่หลากหลาย เช่น คุณสามารถใช้คอมโพเนนต์การนำทางกับ Compose, View, Fragment, Activity และแม้แต่เฟรมเวิร์ก UI ที่กำหนดเองได้
คู่มือนี้อธิบายวิธีใช้คอมโพเนนต์การนำทางเพื่อไปยังปลายทางในบริบทต่างๆ
ใช้ NavController
ประเภทคีย์ที่คุณใช้เพื่อย้ายไปมาระหว่างปลายทางคือ NavController
ดูข้อมูลเพิ่มเติมเกี่ยวกับคลาสและวิธีสร้างอินสแตนซ์ของคลาสได้ที่สร้างตัวควบคุมการนำทาง
คู่มือนี้จะอธิบายรายละเอียดวิธีใช้
นำทาง
ไม่ว่าคุณจะใช้เฟรมเวิร์ก UI ใด ก็มีฟังก์ชันเดียวที่คุณใช้เพื่อไปยังปลายทางได้
คือ NavController.navigate()
มีโอเวอร์โหลดมากมายสำหรับ navigate() การโอเวอร์โหลดที่คุณควรเลือกจะสอดคล้องกับบริบทที่แน่นอนของคุณ เช่น คุณควรใช้การโอเวอร์โหลดหนึ่งเมื่อไปยัง Composable และอีกหนึ่งเมื่อไปยัง View
ส่วนต่อไปนี้จะอธิบายการโอเวอร์โหลด navigate() ที่สำคัญบางส่วนที่คุณใช้ได้
ไปยัง Composable
หากต้องการไปยัง Composable คุณควรใช้ NavController.navigate<T>
เมื่อมีการโอเวอร์โหลดนี้ navigate() จะใช้อาร์กิวเมนต์ route เดียวที่คุณส่งประเภท ซึ่งเป็นกุญแจสำคัญในการเดินทางไปยังจุดหมาย
@Serializable
object FriendsList
navController.navigate(route = FriendsList)
หากต้องการไปยัง Composable ในกราฟการนำทาง ให้กำหนด NavGraph ก่อนเพื่อให้แต่ละปลายทางสอดคล้องกับประเภท สำหรับ
Composable คุณทำได้โดยใช้ฟังก์ชัน composable()
เปิดเผยเหตุการณ์จาก Composable
เมื่อฟังก์ชันที่ประกอบกันได้ต้องไปยังหน้าจอใหม่ คุณไม่ควรส่ง
การอ้างอิงไปยัง NavController เพื่อให้เรียก navigate() ได้โดยตรง
ตามหลักการโฟลว์ข้อมูลแบบทิศทางเดียว (UDF) คอมโพสได้
ควรแสดงเหตุการณ์ที่ NavController จัดการแทน
กล่าวโดยตรงคือ Composable ของคุณควรมีพารามิเตอร์ประเภท () -> Unit
เมื่อเพิ่มปลายทางไปยัง NavHost ด้วยฟังก์ชัน composable()
ให้ส่งการเรียกไปยัง NavController.navigate()
ดูตัวอย่างได้ในส่วนย่อยต่อไปนี้
ตัวอย่าง
เพื่อเป็นการสาธิตส่วนก่อนหน้า ให้สังเกตจุดต่อไปนี้ใน ข้อมูลโค้ดต่อไปนี้
- ปลายทางแต่ละแห่งในกราฟสร้างขึ้นโดยใช้เส้นทาง ซึ่งเป็นออบเจ็กต์หรือคลาสที่สามารถแปลงเป็นอนุกรมได้ซึ่งอธิบายข้อมูลที่ปลายทางนั้นๆ ต้องการ
- ฟังก์ชันที่ประกอบกันได้
MyAppNavHostจะมีอินสแตนซ์NavController - ดังนั้น การเรียกใช้
navigate()ควรเกิดขึ้นที่นั่นและไม่ควรเกิดขึ้นใน Composable ระดับล่าง เช่นProfileScreen ProfileScreenมีปุ่มที่นำผู้ใช้ไปยังFriendsListเมื่อคลิก แต่จะไม่เรียกใช้navigate()ด้วยตัวเอง- แต่ปุ่มจะเรียกฟังก์ชันที่แสดงเป็นพารามิเตอร์
onNavigateToFriends - เมื่อ
MyAppNavHostเพิ่มProfileScreenลงในกราฟการนำทาง สำหรับonNavigateToFriendsจะส่ง Lambda ที่เรียกnavigate(route = FriendsList) - ซึ่งช่วยให้มั่นใจได้ว่าเมื่อผู้ใช้กดปุ่ม
ProfileScreenผู้ใช้จะ ไปยังFriendsListScreenได้อย่างถูกต้อง
@Serializable
object Profile
@Serializable
object FriendsList
@Composable
fun MyAppNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
) {
NavHost(
modifier = modifier,
navController = navController,
startDestination = Profile
) {
composable<Profile> {
ProfileScreen(
onNavigateToFriends = { navController.navigate(route = FriendsList) },
/*...*/
)
}
composable<FriendsList> { FriendsListScreen(/*...*/) }
}
}
@Composable
fun ProfileScreen(
onNavigateToFriends: () -> Unit,
/*...*/
) {
/*...*/
Button(onClick = onNavigateToFriends) {
Text(text = "See friends list")
}
}
ไปยังส่วนต่างๆ โดยใช้รหัสจำนวนเต็ม
หากต้องการไปยังปลายทางโดยใช้รหัสจำนวนเต็ม ให้เรียกใช้navigate(int)
โอเวอร์โหลด โดยจะใช้รหัสทรัพยากรของทั้งการกระทําหรือปลายทาง ข้อมูลโค้ดต่อไปนี้แสดงวิธีใช้การโอเวอร์โหลดนี้เพื่อไปยังViewTransactionsFragment
Kotlin
viewTransactionsButton.setOnClickListener { view ->
view.findNavController().navigate(R.id.viewTransactionsAction)
}
Java
viewTransactionsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Navigation.findNavController(view).navigate(R.id.viewTransactionsAction);
}
});
เมื่อไปยังส่วนต่างๆ โดยใช้รหัส คุณควรใช้การดำเนินการหากเป็นไปได้ การดำเนินการ ให้ข้อมูลเพิ่มเติมในกราฟการนำทาง โดยแสดงให้เห็นว่า ปลายทางเชื่อมต่อกันอย่างไร
ไปยังส่วนต่างๆ จาก Compose ในแอปที่ใช้ Fragment
หากใช้ Jetpack Compose ภายในสถาปัตยกรรมการนำทางที่อิงตาม Fragment (เช่น ในแอปที่ใช้ทั้ง View และ Compose) คุณจะใช้เส้นทาง Compose ที่ปลอดภัยตามประเภทเพื่อไปยังส่วนต่างๆ โดยตรงไม่ได้ แต่คุณต้องใช้รหัสจำนวนเต็ม (การดำเนินการ) ที่กำหนดไว้ในกราฟการนำทาง XML
หากต้องการเปลี่ยนปลายทางจากโค้ด Compose ให้แสดงเหตุการณ์ (Lambda) จาก Composable ดังนี้
@Composable
fun MyScreen(onNavigateToProfile: () -> Unit) {
Button(onClick = { onNavigateToProfile() }) {
Text("Go to Profile")
}
}
ใน Fragment ให้เชื่อมต่อ Compose กับคอมโพเนนต์การนำทางที่อิงตาม Fragment
โดยเรียกใช้ NavController ของ Fragment เมื่อมีการทริกเกอร์เหตุการณ์
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
return ComposeView(requireContext()).apply {
setContent {
MyScreen(onNavigateToProfile = { findNavController().navigate(R.id.nav_profile) })
}
}
}
แนวทางนี้ช่วยให้ Composable สามารถนำกลับมาใช้ซ้ำและทดสอบได้ เนื่องจากไม่ได้
ขึ้นอยู่กับ NavController ของ Fragment โดยตรง
ไปยังส่วนต่างๆ โดยใช้ NavDeepLinkRequest
หากต้องการไปยังปลายทางของ Implicit Deep Link ให้ใช้การโอเวอร์โหลด
navigate(NavDeepLinkRequest) ข้อมูลโค้ดต่อไปนี้แสดงการติดตั้งใช้งานเมธอดนี้
Kotlin
val request = NavDeepLinkRequest.Builder
.fromUri("android-app://androidx.navigation.app/profile".toUri())
.build()
findNavController().navigate(request)
Java
NavDeepLinkRequest request = NavDeepLinkRequest.Builder
.fromUri(Uri.parse("android-app://androidx.navigation.app/profile"))
.build()
NavHostFragment.findNavController(this).navigate(request)
การไปยังลิงก์โดยใช้รหัสการกระทำหรือรหัสปลายทางนั้นแตกต่างจากการไปยังลิงก์ใดๆ ในกราฟของคุณ ไม่ว่าปลายทางจะมองเห็นได้หรือไม่ก็ตาม คุณสามารถ ไปยังจุดหมายในกราฟปัจจุบันหรือจุดหมายในกราฟที่ แตกต่างกันโดยสิ้นเชิง
การดำเนินการและประเภท MIME
นอกจาก Uri แล้ว NavDeepLinkRequest ยังรองรับ Deep Link ที่มี
การดำเนินการและประเภท MIME ด้วย หากต้องการเพิ่มการดำเนินการในคำขอ ให้ใช้
fromAction() หรือ setAction() หากต้องการเพิ่มประเภท MIME ลงในคำขอ
ให้ใช้ fromMimeType() หรือ setMimeType()
หากต้องการให้ NavDeepLinkRequest ตรงกับปลายทางของ Implicit Deep Link โดยนัยอย่างถูกต้อง
URI, การดำเนินการ และประเภท MIME ต้องตรงกับ NavDeepLink ใน
ปลายทาง URI ต้องตรงกับรูปแบบ การดำเนินการต้องตรงกันทุกประการ
และประเภท MIME ต้องเกี่ยวข้อง เช่น image/jpg จะตรงกับ
image/\*
บริบทเพิ่มเติม
เอกสารนี้ครอบคลุมวิธีใช้ NavController.navigate() ในกรณีการใช้งานที่พบบ่อยที่สุด
อย่างไรก็ตาม ฟังก์ชันนี้มีการโอเวอร์โหลดหลายอย่างที่คุณใช้ได้ในบริบทต่างๆ และใช้ร่วมกับเฟรมเวิร์ก UI ใดก็ได้ ดูรายละเอียดเพิ่มเติมเกี่ยวกับการโอเวอร์โหลดเหล่านี้ในเอกสารประกอบอ้างอิง
อ่านเพิ่มเติม
ดูข้อมูลเพิ่มเติมได้ที่หน้าต่อไปนี้
- สร้างตัวควบคุมการนำทาง
- การนำทางและแบ็กสแต็ก
- ไปยังส่วนต่างๆ ด้วยตัวเลือก
- ความปลอดภัยในการกำหนดประเภทใน Kotlin DSL และ Navigation Compose