ขั้นตอนการเข้าสู่ระบบ วิซาร์ด หรือขั้นตอนย่อยอื่นๆ ภายในแอปมักจะเหมาะสมที่สุด แสดงเป็นกราฟการนำทางที่ซ้อนกัน โดยการซ้อนกันด้วยตัวเอง การนำทางย่อยในลักษณะนี้ทำให้ขั้นตอนหลักของ UI ของแอปง่ายขึ้น ทำความเข้าใจและจัดการ
นอกจากนี้ กราฟที่ซ้อนกันยังนำมาใช้ซ้ำได้ และยังให้ระดับของ
การห่อหุ้มข้อมูล—ปลายทางนอกกราฟที่ซ้อนกันไม่มีการเข้าถึงโดยตรง
ปลายทางใดๆ ภายในกราฟที่ซ้อนกัน แต่ควร
navigate()
กับกราฟแบบซ้อนกัน โดยที่ตรรกะภายในสามารถ
เปลี่ยนแปลงโดยไม่ส่งผลกระทบต่อส่วนที่เหลือของกราฟ
ตัวอย่าง
กราฟการนำทางระดับบนสุดของแอปควรขึ้นต้นด้วย ที่ผู้ใช้จะเห็นเมื่อเปิดแอป และควรมี ปลายทางที่ผู้ใช้จะเห็นเมื่อไปยังแอปของคุณ
![](https://developer.android.google.cn/static/images/topic/libraries/architecture/navigation-design-graph-top-level.png?authuser=19&hl=th)
ใช้กราฟการนำทางระดับบนสุดจากรูปที่ 1 เป็นตัวอย่าง สมมติว่าคุณ ต้องการกำหนดให้ผู้ใช้ดูหน้าจอ title_screen และลงทะเบียน เมื่อแอปเปิดขึ้นเป็นครั้งแรก หลังจากนั้น ข้อมูลผู้ใช้ ไว้ และเมื่อเปิดแอปในครั้งถัดไป คุณควรนำ กับหน้าจอ match
สำหรับแนวทางปฏิบัติที่ดีที่สุด ให้ตั้งค่าหน้าจอการจับคู่เป็นปลายทางเริ่มต้นของ กราฟการนำทางระดับบนสุด และย้ายชื่อและหน้าจอการลงทะเบียนไปยัง ดังแสดงในรูปที่ 1
![](https://developer.android.google.cn/static/images/topic/libraries/architecture/navigation-design-graph-nested.png?authuser=19&hl=th)
เมื่อหน้าจอการจับคู่เปิดขึ้น ให้ตรวจสอบว่ามีผู้ใช้ที่ลงทะเบียนแล้วหรือไม่ ถ้า ผู้ใช้ยังไม่ได้ลงทะเบียน โปรดนำผู้ใช้ไปยังหน้าจอการลงทะเบียน
ดูข้อมูลเพิ่มเติมเกี่ยวกับสถานการณ์การนำทางแบบมีเงื่อนไขได้ที่แบบมีเงื่อนไข การนำทาง
เขียน
หากต้องการสร้างกราฟการนำทางที่ซ้อนกันโดยใช้การเขียน ให้ใช้
NavGraphBuilder.navigation()
คุณใช้ navigation()
เช่นเดียวกับ
NavGraphBuilder.composable()
และ NavGraphBuilder.dialog()
เมื่อเพิ่มปลายทางลงในกราฟ
ความแตกต่างหลักคือ navigation
จะสร้างกราฟแบบซ้อนแทนที่
ปลายทางใหม่ จากนั้นคุณจะโทรหา composable()
และ dialog()
ภายใน
lambda ของ navigation()
เพื่อเพิ่มปลายทางลงในกราฟแบบซ้อน
พิจารณาวิธีที่ข้อมูลโค้ดต่อไปนี้ใช้งานกราฟในรูปที่ 2 โดยใช้ เขียน:
// Routes
@Serializable object Title
@Serializable object Register
// Route for nested graph
@Serializable object Game
// Routes inside nested graph
@Serializable object Match
@Serializable object InGame
@Serializable object ResultsWinner
@Serializable object GameOver
NavHost(navController, startDestination = Title) {
composable<Title> {
TitleScreen(
onPlayClicked = { navController.navigate(route = Register) },
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<Register> {
RegisterScreen(
onSignUpComplete = { navController.navigate(route = Game) }
)
}
navigation<Game>(startDestination = Match) {
composable<Match> {
MatchScreen(
onStartGame = { navController.navigate(route = InGame) }
)
}
composable<InGame> {
InGameScreen(
onGameWin = { navController.navigate(route = ResultsWinner) },
onGameLose = { navController.navigate(route = GameOver) }
)
}
composable<ResultsWinner> {
ResultsWinnerScreen(
onNextMatchClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
},
onLeaderboardsClicked = { /* Navigate to leaderboards */ }
)
}
composable<GameOver> {
GameOverScreen(
onTryAgainClicked = {
navController.navigate(route = Match) {
popUpTo(route = Match) { inclusive = true }
}
}
)
}
}
}
ในการนำทางไปยังปลายทางที่ซ้อนกันโดยตรง ให้ใช้ประเภทเส้นทางเหมือนกับที่คุณทำ ไปยังปลายทางอื่น เพราะเส้นทางเป็นแนวคิดที่ทุกคนใช้กันทั่วโลก ระบุปลายทางที่ทุกหน้าจอสามารถไปถึง
navController.navigate(route = Match)
XML
เมื่อใช้ XML คุณสามารถใช้ตัวแก้ไขการนำทางเพื่อสร้างกราฟแบบซ้อนได้ โดยทำตามขั้นตอนต่อไปนี้
- ในตัวแก้ไขการนำทาง ให้กดปุ่ม Shift ค้างไว้แล้วคลิก ปลายทางที่คุณต้องการรวมในกราฟที่ซ้อนกัน
คลิกขวาเพื่อเปิดเมนูตามบริบท แล้วเลือกย้ายไปที่กราฟแบบซ้อน > กราฟใหม่ ปลายทางจะอยู่ภายในกราฟแบบซ้อน รูปที่ 2 แสดงกราฟที่ซ้อนกันในตัวแก้ไขการนำทาง ดังนี้
วันที่ รูปที่ 2 กราฟที่ฝังในเครื่องมือแก้ไขการนำทาง คลิกกราฟที่ฝัง แอตทริบิวต์ต่อไปนี้จะปรากฏใน แผงแอตทริบิวต์:
- ประเภท ซึ่งมี "กราฟที่ซ้อนกัน"
- ID ซึ่งมีรหัสที่ระบบกำหนดสำหรับกราฟที่ซ้อนกัน ช่วงเวลานี้ รหัสใช้เพื่ออ้างอิงกราฟที่ซ้อนกันจากโค้ดของคุณ
ดับเบิลคลิกบนกราฟที่ซ้อนกันเพื่อแสดงปลายทาง
คลิกแท็บข้อความเพื่อสลับเป็นมุมมอง XML กราฟการนำทางที่ฝังไว้ มีการเพิ่มลงในกราฟแล้ว กราฟการนำทางนี้มี
navigation
ของตัวเอง พร้อมด้วยรหัสของตนเองและแอตทริบิวต์startDestination
ที่ ชี้ไปยังปลายทางแรกในกราฟที่ซ้อนกัน<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" app:startDestination="@id/mainFragment"> <fragment android:id="@+id/mainFragment" android:name="com.example.cashdog.cashdog.MainFragment" android:label="fragment_main" tools:layout="@layout/fragment_main" > <action android:id="@+id/action_mainFragment_to_sendMoneyGraph" app:destination="@id/sendMoneyGraph" /> <action android:id="@+id/action_mainFragment_to_viewBalanceFragment" app:destination="@id/viewBalanceFragment" /> </fragment> <fragment android:id="@+id/viewBalanceFragment" android:name="com.example.cashdog.cashdog.ViewBalanceFragment" android:label="fragment_view_balance" tools:layout="@layout/fragment_view_balance" /> <navigation android:id="@+id/sendMoneyGraph" app:startDestination="@id/chooseRecipient"> <fragment android:id="@+id/chooseRecipient" android:name="com.example.cashdog.cashdog.ChooseRecipient" android:label="fragment_choose_recipient" tools:layout="@layout/fragment_choose_recipient"> <action android:id="@+id/action_chooseRecipient_to_chooseAmountFragment" app:destination="@id/chooseAmountFragment" /> </fragment> <fragment android:id="@+id/chooseAmountFragment" android:name="com.example.cashdog.cashdog.ChooseAmountFragment" android:label="fragment_choose_amount" tools:layout="@layout/fragment_choose_amount" /> </navigation> </navigation>
ส่งรหัสทรัพยากรของการดำเนินการที่เชื่อมต่อกราฟรากในโค้ดของคุณ กับกราฟที่ซ้อนกัน:
Kotlin
view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)
Java
Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
- กลับไปที่แท็บ Design แล้วกลับไปที่กราฟรากโดยคลิก ราก
อ้างอิงกราฟการนำทางอื่นๆ ด้วยฟังก์ชัน include
อีกวิธีหนึ่งในการปรับโครงสร้างกราฟเป็นโมดูลคือการรวมกราฟ 1 รายการภายใน
อีกรายการโดยใช้เอลิเมนต์ <include>
ในกราฟการนำทางระดับบน ช่วงเวลานี้
ช่วยให้กำหนดกราฟที่รวมไว้ในโมดูลหรือโปรเจ็กต์แยกต่างหากได้
ทั้งหมดจึงนำกลับมาใช้ใหม่ได้
ข้อมูลโค้ดต่อไปนี้แสดงวิธีที่คุณสามารถใช้ <include>
<!-- (root) nav_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/fragment">
<strong><include app:graph="@navigation/included_graph" /></strong>
<fragment
android:id="@+id/fragment"
android:name="com.example.myapplication.BlankFragment"
android:label="Fragment in Root Graph"
tools:layout="@layout/fragment_blank">
<strong><action
android:id="@+id/action_fragment_to_second_graph"
app:destination="@id/second_graph" /></strong>
</fragment>
...
</navigation>
<!-- included_graph.xml -->
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<strong>android:id="@+id/second_graph"</strong>
app:startDestination="@id/includedStart">
<fragment
android:id="@+id/includedStart"
android:name="com.example.myapplication.IncludedStart"
android:label="fragment_included_start"
tools:layout="@layout/fragment_included_start" />
</navigation>
แหล่งข้อมูลเพิ่มเติม
หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการนำทาง โปรดดูแหล่งข้อมูลเพิ่มเติมต่อไปนี้