ออกแบบกราฟการนำทาง

คอมโพเนนต์การนำทางใช้กราฟการนำทางเพื่อจัดการการนำทางของแอป กราฟการนําทางคือโครงสร้างข้อมูลที่ประกอบด้วยปลายทางแต่ละแห่งภายในแอปและการเชื่อมต่อระหว่างปลายทางเหล่านั้น

ประเภทปลายทาง

ปลายทางทั่วไปมี 3 ประเภท ได้แก่ โฮสต์ กล่องโต้ตอบ และกิจกรรม ตารางต่อไปนี้แสดงประเภทปลายทาง 3 ประเภทนี้และวัตถุประสงค์

ประเภท

คำอธิบาย

กรณีการใช้งาน

โฮสต์

เติมโฮสต์การนําทางทั้งหมด กล่าวคือ ขนาดของปลายทางที่โฮสต์จะเหมือนกับขนาดของโฮสต์การนําทาง และปลายทางก่อนหน้าจะมองไม่เห็น

หน้าจอหลักและหน้าจอรายละเอียด

Dialog

แสดงคอมโพเนนต์ UI ที่วางซ้อน UI นี้ไม่ได้เชื่อมโยงกับตำแหน่งหรือขนาดของโฮสต์การนำทาง โดยจุดหมายก่อนหน้าจะปรากฏใต้จุดหมาย

การแจ้งเตือน การเลือก แบบฟอร์ม

กิจกรรม

แสดงหน้าจอหรือฟีเจอร์ที่ไม่ซ้ำกันภายในแอป

ใช้เป็นจุดสิ้นสุดของกราฟการนําทางที่เริ่มกิจกรรม Android ใหม่ซึ่งจัดการแยกจากคอมโพเนนต์การนําทาง

ในการพัฒนา Android สมัยใหม่ แอปประกอบด้วยกิจกรรมเดียว ดังนั้น ปลายทางของกิจกรรมจึงเหมาะสําหรับใช้เมื่อโต้ตอบกับกิจกรรมของบุคคลที่สามหรือเป็นส่วนหนึ่งของกระบวนการย้ายข้อมูล

เอกสารนี้มีตัวอย่างปลายทางที่โฮสต์ ซึ่งเป็นปลายทางที่พบบ่อยและเป็นพื้นฐานที่สุด ดูข้อมูลเกี่ยวกับปลายทางอื่นๆ ได้จากคู่มือต่อไปนี้

เฟรมเวิร์ก

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

  • เขียน: ใช้คอมโพสิเบิล NavHost เพิ่ม NavGraph โดยใช้ Kotlin DSL คุณสร้างกราฟได้ 2 วิธี ดังนี้
    • เป็นส่วนหนึ่งของ NavHost: สร้างกราฟการนำทางโดยตรงเป็นส่วนหนึ่งของการเพิ่ม NavHost
    • แบบเป็นโปรแกรม: ใช้เมธอด NavController.createGraph() เพื่อสร้าง NavGraph และส่งไปยัง NavHost โดยตรง
  • ส่วนย่อย: เมื่อใช้ส่วนย่อยกับเฟรมเวิร์ก UI ของมุมมอง ให้ใช้ NavHostFragment เป็นโฮสต์ การสร้างกราฟการนําทางมีหลายวิธี ดังนี้
    • แบบเป็นโปรแกรม: ใช้ Kotlin DSL เพื่อสร้าง NavGraph และนำไปใช้กับ NavHostFragment โดยตรง
      • ฟังก์ชัน createGraph() ที่ใช้ใน Kotlin DSL สำหรับทั้งข้อบังคับและ Compose นั้นเหมือนกัน
    • XML: เขียนโฮสต์การนําทางและกราฟใน XML โดยตรง
    • เครื่องมือแก้ไขของ Android Studio: ใช้เครื่องมือแก้ไข GUI ใน Android Studio เพื่อสร้างและปรับกราฟเป็นไฟล์ทรัพยากร XML

เขียน

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

ใช้คำอธิบายประกอบ @Serializable เพื่อสร้างเมธอดการแปลงเป็นอนุกรมและถอดรหัสที่จำเป็นโดยอัตโนมัติสำหรับประเภทเส้นทาง คําอธิบายประกอบนี้มาจากปลั๊กอินการแปลงข้อมูล Kotlin ทําตามวิธีการเหล่านี้เพื่อเพิ่มปลั๊กอินนี้

เมื่อกําหนดเส้นทางแล้ว ให้ใช้คอมโพสิเบิล NavHost เพื่อสร้างกราฟการนําทาง ลองดูตัวอย่างต่อไปนี้

@Serializable
object Profile
@Serializable
object FriendsList

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile) {
    composable { ProfileScreen( /* ... */ ) }
    composable { FriendsListScreen( /* ... */ ) }
    // Add more destinations similarly.
}
  1. ออบเจ็กต์ที่ซีเรียลไลซ์ได้แสดงถึงเส้นทาง 2 เส้นทาง ได้แก่ Profile และ FriendsList
  2. การเรียกใช้คอมโพสิเบิล NavHost จะส่ง NavController และเส้นทางสำหรับจุดหมายเริ่มต้น
  3. แลมดาที่ส่งไปยัง NavHost จะเรียกใช้ NavController.createGraph() ในท้ายที่สุดและแสดงผล NavGraph
  4. แต่ละเส้นทางจะส่งเป็นอาร์กิวเมนต์ประเภทไปยัง NavGraphBuilder.composable() ซึ่งจะเพิ่มปลายทางไปยัง NavGraph ที่ได้
  5. Lambda ที่ส่งไปยัง composable คือสิ่งที่ NavHost แสดงสําหรับปลายทางนั้น

ทําความเข้าใจเกี่ยวกับ Lambda

หากต้องการทําความเข้าใจ Lambda ที่สร้าง NavGraph ได้ดียิ่งขึ้น ให้ลองสร้างกราฟเดียวกันกับในสนิปเพลตก่อนหน้า โดยสร้าง NavGraph แยกต่างหากโดยใช้ NavController.createGraph() แล้วส่งไปยัง NavHost โดยตรง ดังนี้

val navGraph by remember(navController) {
  navController.createGraph(startDestination = Profile)) {
    composable { ProfileScreen( /* ... */ ) }
    composable { FriendsListScreen( /* ... */ ) }
  }
}
NavHost(navController, navGraph)

ส่งอาร์กิวเมนต์

หากต้องการส่งข้อมูลไปยังปลายทาง ให้กําหนดเส้นทางด้วยคลาสที่มีพารามิเตอร์ เช่น เส้นทาง Profile เป็นคลาสข้อมูลที่มีพารามิเตอร์ name

@Serializable
data class Profile(val name: String)

เมื่อใดก็ตามที่คุณต้องส่งอาร์กิวเมนต์ไปยังปลายทางนั้น คุณก็สร้างอินสแตนซ์ของคลาสเส้นทางโดยส่งอาร์กิวเมนต์ไปยังคอนสตรัคเตอร์ของคลาส

สำหรับอาร์กิวเมนต์ที่ไม่บังคับ ให้สร้างฟิลด์ที่อนุญาตค่า Null ที่มีค่าเริ่มต้น

@Serializable
data class Profile(val nickname: String? = null)

รับอินสแตนซ์เส้นทาง

คุณดูอินสแตนซ์เส้นทางได้ด้วย NavBackStackEntry.toRoute() หรือ SavedStateHandle.toRoute() เมื่อคุณสร้างปลายทางโดยใช้ composable() NavBackStackEntry จะพร้อมใช้งานเป็นพารามิเตอร์

@Serializable
data class Profile(val name: String)

val navController = rememberNavController()

NavHost(navController = navController, startDestination = Profile(name="John Smith")) {
    composable { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(name = profile.name) }
}

โปรดสังเกตสิ่งต่อไปนี้ในข้อมูลโค้ดนี้

  • เส้นทาง Profile จะระบุปลายทางเริ่มต้นในกราฟการนำทาง โดยมี "John Smith" เป็นอาร์กิวเมนต์สําหรับ name
  • ปลายทางคือบล็อก composable{}
  • คอมโพสิเบิล ProfileScreen จะใช้ค่าของ profile.name สำหรับอาร์กิวเมนต์ name ของตัวเอง
  • ดังนั้น ค่า "John Smith" จึงส่งผ่านไปยัง ProfileScreen

ตัวอย่างขั้นต่ำ

ตัวอย่างที่สมบูรณ์ของ NavController และ NavHost ที่ทำงานร่วมกัน

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Define the ProfileScreen composable.
@Composable
fun ProfileScreen(
    profile: Profile
    onNavigateToFriendsList: () -> Unit,
  ) {
  Text("Profile for ${profile.name}")
  Button(onClick = { onNavigateToFriendsList() }) {
    Text("Go to Friends List")
  }
}

// Define the FriendsListScreen composable.
@Composable
fun FriendsListScreen(onNavigateToProfile: () -> Unit) {
  Text("Friends List")
  Button(onClick = { onNavigateToProfile() }) {
    Text("Go to Profile")
  }
}

// Define the MyApp composable, including the `NavController` and `NavHost`.
@Composable
fun MyApp() {
  val navController = rememberNavController()
  NavHost(navController, startDestination = Profile(name = "John Smith")) {
    composable { backStackEntry ->
        val profile: Profile = backStackEntry.toRoute()
        ProfileScreen(
            profile = profile,
            onNavigateToFriendsList = {
                navController.navigate(route = FriendsList)
            }
        )
    }
    composable {
      FriendsListScreen(
        onNavigateToProfile = {
          navController.navigate(
            route = Profile(name = "Aisha Devi")
          )
        }
      )
    }
  }
}

ดังที่ข้อมูลโค้ดแสดง แทนที่จะส่ง NavController ไปยังคอมโพสิเบิล ให้แสดงเหตุการณ์ต่อ NavHost กล่าวคือ คอมโพสิเบิลควรมีพารามิเตอร์ประเภท () -> Unit ซึ่ง NavHost ส่งผ่าน Lambda ที่เรียก NavController.navigate()

ส่วนย่อย

ดังที่ระบุไว้ในส่วนก่อนหน้า เมื่อใช้ FRG คุณจะมีตัวเลือกในการสร้างกราฟการนําทางแบบเป็นโปรแกรมโดยใช้ Kotlin DSL, XML หรือเครื่องมือแก้ไขของ Android Studio

ส่วนต่อไปนี้จะอธิบายแนวทางต่างๆ เหล่านี้โดยละเอียด

แบบเป็นโปรแกรม

Kotlin DSL มีวิธีแบบเป็นโปรแกรมในการสร้างกราฟการนำทางด้วยฟragment วิธีนี้เรียบร้อยและทันสมัยกว่าการใช้ไฟล์ทรัพยากร XML ในหลายๆ ด้าน

ลองดูตัวอย่างต่อไปนี้ที่ใช้กราฟการนําทางแบบ 2 หน้าจอ

ก่อนอื่นคุณต้องสร้าง NavHostFragment ซึ่งต้องไม่มีองค์ประกอบ app:navGraph ดังนี้

 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

            android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

ถัดไป ให้ส่ง id ของ NavHostFragment ไปยัง NavController.findNavController ซึ่งจะเชื่อมโยง NavController กับ NavHostFragment

จากนั้นการเรียกใช้ NavController.createGraph() จะลิงก์กราฟกับ NavController และ NavHostFragment ด้วย

@Serializable
data class Profile(val name: String)

@Serializable
object FriendsList

// Retrieve the NavController.
val navController = findNavController(R.id.nav_host_fragment)

// Add the graph to the NavController with `createGraph()`.
navController.graph = navController.createGraph(
    startDestination = Profile(name = "John Smith")
) {
    // Associate each destination with one of the route constants.
    fragment, Profile> {
        label = "Profile"
    }

    fragment, FriendsList>() {
        label = "Friends List"
    }

    // Add other fragment destinations similarly.
}

การใช้ DSL ในลักษณะนี้คล้ายกับเวิร์กโฟลว์ที่ระบุไว้ในส่วนเขียนก่อนหน้า ตัวอย่างเช่น ทั้งที่นี่และที่นั่น ฟังก์ชัน NavController.createGraph() จะสร้าง NavGraph ในทํานองเดียวกัน ขณะที่ NavGraphBuilder.composable() เพิ่มปลายทางแบบคอมโพสิเบิลลงในกราฟ NavGraphBuilder.fragment() จะเพิ่มปลายทางของข้อมูลโค้ด

ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีใช้ Kotlin DSL ได้ที่สร้างกราฟด้วย DSL ของ NavGraphBuilder

XML

คุณเขียน XML ของคุณเองได้โดยตรง ตัวอย่างต่อไปนี้จะแสดงภาพสะท้อนและเทียบเท่ากับตัวอย่างแบบ 2 หน้าจอจากส่วนก่อนหน้า

ก่อนอื่น ให้สร้าง NavHostFragment ซึ่งทำหน้าที่เป็นโฮสต์การนำทางซึ่งมีกราฟการนำทางจริง

การใช้งาน NavHostFragment ขั้นต่ำ

 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

            android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph" />


NavHostFragment มีแอตทริบิวต์ app:navGraph ใช้แอตทริบิวต์นี้เพื่อเชื่อมต่อกราฟการนำทางกับโฮสต์การนำทาง ต่อไปนี้คือตัวอย่างวิธีใช้กราฟ

 xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/nav_graph"
    app:startDestination="@id/profile">

            android:id="@+id/profile"
        android:name="com.example.ProfileFragment"
        android:label="Profile">

        
                    android:id="@+id/action_profile_to_friendslist"
            app:destination="@id/friendslist" />
    

            android:id="@+id/friendslist"
        android:name="com.example.FriendsListFragment"
        android:label="Friends List" />

    

คุณใช้การดำเนินการเพื่อกำหนดการเชื่อมต่อระหว่างปลายทางต่างๆ ในตัวอย่างนี้ ข้อมูลโค้ด profile มีการดำเนินการที่ไปยัง friendslist ดูข้อมูลเพิ่มเติมได้ที่ใช้การดําเนินการและเศษข้อมูลการนําทาง

ผู้แก้ไข

คุณจัดการกราฟการนําทางของแอปได้โดยใช้เครื่องมือแก้ไขการนําทางใน Android Studio โดยพื้นฐานแล้วนี่คือ GUI ที่คุณสามารถใช้สร้างและแก้ไข NavigationFragment XML ได้ ดังที่แสดงในส่วนก่อนหน้า

ดูข้อมูลเพิ่มเติมได้ที่เครื่องมือแก้ไขการนําทาง

กราฟแบบฝัง

คุณยังใช้กราฟที่ซ้อนกันได้ด้วย ซึ่งเกี่ยวข้องกับการใช้กราฟเป็นปลายทางการนำทาง ดูข้อมูลเพิ่มเติมได้ที่กราฟที่ฝัง

อ่านเพิ่มเติม

ดูแนวคิดการนําทางหลักเพิ่มเติมได้ในคู่มือต่อไปนี้

  • ภาพรวม: อย่าลืมอ่านภาพรวมทั่วไปของคอมโพเนนต์การนำทาง
  • ปลายทางของกิจกรรม: ตัวอย่างวิธีใช้ปลายทางที่จะนําผู้ใช้ไปยังกิจกรรม
  • ปลายทางของกล่องโต้ตอบ: ตัวอย่างวิธีสร้างปลายทางที่จะนําผู้ใช้ไปยังกล่องโต้ตอบ
  • ไปยังจุดหมาย: คู่มือโดยละเอียดที่ครอบคลุมวิธีไปยังจุดหมายหนึ่งๆ
  • กราฟที่ฝัง: คำแนะนำโดยละเอียดเกี่ยวกับวิธีฝังกราฟการนำทางกราฟหนึ่งภายในอีกกราฟหนึ่ง