กราฟแบบฝัง

ขั้นตอนการเข้าสู่ระบบ วิซาร์ด หรือขั้นตอนย่อยอื่นๆ ภายในแอปมักจะเหมาะสมที่สุด แสดงเป็นกราฟการนำทางที่ซ้อนกัน โดยการซ้อนกันด้วยตัวเอง การนำทางย่อยในลักษณะนี้ทำให้ขั้นตอนหลักของ UI ของแอปง่ายขึ้น ทำความเข้าใจและจัดการ

นอกจากนี้ กราฟที่ซ้อนกันยังนำมาใช้ซ้ำได้ และยังให้ระดับของ การห่อหุ้มข้อมูล—ปลายทางนอกกราฟที่ซ้อนกันไม่มีการเข้าถึงโดยตรง ปลายทางใดๆ ภายในกราฟที่ซ้อนกัน แต่ควร navigate() กับกราฟแบบซ้อนกัน โดยที่ตรรกะภายในสามารถ เปลี่ยนแปลงโดยไม่ส่งผลกระทบต่อส่วนที่เหลือของกราฟ

ตัวอย่าง

กราฟการนำทางระดับบนสุดของแอปควรขึ้นต้นด้วย ที่ผู้ใช้จะเห็นเมื่อเปิดแอป และควรมี ปลายทางที่ผู้ใช้จะเห็นเมื่อไปยังแอปของคุณ

วันที่
รูปที่ 1 กราฟการนำทางระดับบนสุด

ใช้กราฟการนำทางระดับบนสุดจากรูปที่ 1 เป็นตัวอย่าง สมมติว่าคุณ ต้องการกำหนดให้ผู้ใช้ดูหน้าจอ title_screen และลงทะเบียน เมื่อแอปเปิดขึ้นเป็นครั้งแรก หลังจากนั้น ข้อมูลผู้ใช้ ไว้ และเมื่อเปิดแอปในครั้งถัดไป คุณควรนำ กับหน้าจอ match

สำหรับแนวทางปฏิบัติที่ดีที่สุด ให้ตั้งค่าหน้าจอการจับคู่เป็นปลายทางเริ่มต้นของ กราฟการนำทางระดับบนสุด และย้ายชื่อและหน้าจอการลงทะเบียนไปยัง ดังแสดงในรูปที่ 1

วันที่
รูปที่ 2 ตอนนี้กราฟการนำทางระดับบนสุดมีกราฟที่ซ้อนกันแล้ว

เมื่อหน้าจอการจับคู่เปิดขึ้น ให้ตรวจสอบว่ามีผู้ใช้ที่ลงทะเบียนแล้วหรือไม่ ถ้า ผู้ใช้ยังไม่ได้ลงทะเบียน โปรดนำผู้ใช้ไปยังหน้าจอการลงทะเบียน

ดูข้อมูลเพิ่มเติมเกี่ยวกับสถานการณ์การนำทางแบบมีเงื่อนไขได้ที่แบบมีเงื่อนไข การนำทาง

เขียน

หากต้องการสร้างกราฟการนำทางที่ซ้อนกันโดยใช้การเขียน ให้ใช้ 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 คุณสามารถใช้ตัวแก้ไขการนำทางเพื่อสร้างกราฟแบบซ้อนได้ โดยทำตามขั้นตอนต่อไปนี้

  1. ในตัวแก้ไขการนำทาง ให้กดปุ่ม Shift ค้างไว้แล้วคลิก ปลายทางที่คุณต้องการรวมในกราฟที่ซ้อนกัน
  2. คลิกขวาเพื่อเปิดเมนูตามบริบท แล้วเลือกย้ายไปที่กราฟแบบซ้อน > กราฟใหม่ ปลายทางจะอยู่ภายในกราฟแบบซ้อน รูปที่ 2 แสดงกราฟที่ซ้อนกันในตัวแก้ไขการนำทาง ดังนี้

    วันที่
    รูปที่ 2 กราฟที่ฝังในเครื่องมือแก้ไขการนำทาง
  3. คลิกกราฟที่ฝัง แอตทริบิวต์ต่อไปนี้จะปรากฏใน แผงแอตทริบิวต์:

    • ประเภท ซึ่งมี "กราฟที่ซ้อนกัน"
    • ID ซึ่งมีรหัสที่ระบบกำหนดสำหรับกราฟที่ซ้อนกัน ช่วงเวลานี้ รหัสใช้เพื่ออ้างอิงกราฟที่ซ้อนกันจากโค้ดของคุณ
  4. ดับเบิลคลิกบนกราฟที่ซ้อนกันเพื่อแสดงปลายทาง

  5. คลิกแท็บข้อความเพื่อสลับเป็นมุมมอง 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>
    
  6. ส่งรหัสทรัพยากรของการดำเนินการที่เชื่อมต่อกราฟรากในโค้ดของคุณ กับกราฟที่ซ้อนกัน:

Kotlin

view.findNavController().navigate(R.id.action_mainFragment_to_sendMoneyGraph)

Java

Navigation.findNavController(view).navigate(R.id.action_mainFragment_to_sendMoneyGraph);
  1. กลับไปที่แท็บ 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>

แหล่งข้อมูลเพิ่มเติม

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการนำทาง โปรดดูแหล่งข้อมูลเพิ่มเติมต่อไปนี้

ตัวอย่าง

Codelab

วิดีโอ