พิมพ์ความปลอดภัยใน Kotlin DSL และการเขียนการนำทาง

คุณใช้ API ที่ปลอดภัยในการกำหนดประเภทในตัวเพื่อมอบความปลอดภัยในการกำหนดประเภทในเวลาคอมไพล์สำหรับกราฟการนำทางได้ API เหล่านี้จะพร้อมใช้งานเมื่อแอปใช้ Navigation Compose หรือ Navigation Kotlin DSL โดยจะพร้อมให้บริการตั้งแต่วันที่ Navigation 2.8.0

API เหล่านี้เทียบเท่ากับสิ่งที่ Safe Args มีให้สำหรับกราฟการนำทาง ที่สร้างขึ้นโดยใช้ XML

กำหนดเส้นทาง

หากต้องการใช้เส้นทางที่ปลอดภัยต่อประเภทใน Compose คุณต้องกำหนดคลาสหรือออบเจ็กต์ที่ทำให้เป็นอนุกรมได้ ซึ่งแสดงถึงเส้นทางของคุณก่อน

หากต้องการกำหนดออบเจ็กต์ที่ทำให้เป็นอนุกรมได้ ให้ใช้คำอธิบายประกอบ @Serializable ที่ได้รับจากปลั๊กอินการทำให้เป็นอนุกรมของ Kotlin คุณเพิ่มปลั๊กอินนี้ลงในโปรเจ็กต์ได้โดยเพิ่มการอ้างอิง เหล่านี้

ใช้กฎต่อไปนี้เพื่อตัดสินใจว่าจะใช้เส้นทางประเภทใด

  • ออบเจ็กต์: ใช้ออบเจ็กต์สำหรับเส้นทางที่ไม่มีอาร์กิวเมนต์
  • คลาส: ใช้คลาสหรือคลาสข้อมูลสำหรับเส้นทางที่มีอาร์กิวเมนต์
  • KClass<T>: ใช้ในกรณีที่ไม่จําเป็นต้องส่งอาร์กิวเมนต์ เช่น คลาสที่ไม่มีพารามิเตอร์ หรือคลาสที่พารามิเตอร์ทั้งหมดมีค่าเริ่มต้น
    1. ตัวอย่างเช่น Profile::class

ในทุกกรณี ออบเจ็กต์หรือคลาสต้องเป็นแบบอนุกรมได้

เช่น

// Define a home route that doesn't take any arguments
@Serializable
object Home

// Define a profile route that takes an ID
@Serializable
data class Profile(val id: String)

สร้างกราฟ

จากนั้นคุณต้องกำหนดกราฟการนำทาง ใช้ฟังก์ชัน composable() เพื่อกำหนด Composable เป็นปลายทางในกราฟการนำทาง

NavHost(navController, startDestination = Home) {
     composable<Home> {
         HomeScreen(onNavigateToProfile = { id ->
             navController.navigate(Profile(id))
         })
     }
     composable<Profile> { backStackEntry ->
         val profile: Profile = backStackEntry.toRoute()
         ProfileScreen(profile.id)
     }
}

โปรดสังเกตสิ่งต่อไปนี้ในตัวอย่างนี้

  • composable() ใช้พารามิเตอร์ประเภท กล่าวคือ composable<Profile>
  • การกำหนดประเภทปลายทางเป็นแนวทางที่มีประสิทธิภาพมากกว่าการส่งroute สตริงตามที่ระบุใน composable("profile")
  • คลาสเส้นทางจะกำหนดประเภทของอาร์กิวเมนต์การนำทางแต่ละรายการ ดังเช่นใน val id: String จึงไม่จำเป็นต้องใช้ NavArgument
  • สำหรับเส้นทางโปรไฟล์ เมธอดส่วนขยาย toRoute() จะสร้างออบเจ็กต์ Profile จาก NavBackStackEntry และอาร์กิวเมนต์ของออบเจ็กต์

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

เข้าถึงอาร์กิวเมนต์ใน ViewModel

หากต้องการเข้าถึงอาร์กิวเมนต์จากเส้นทางที่ปลอดภัยประเภทใน ViewModel คุณสามารถเรียกข้อมูล เส้นทางจาก SavedStateHandle ได้โดยการเรียก SavedStateHandle.toRoute<T>() โดยที่ T คือคลาสเส้นทางของคุณ

class ProfileViewModel(
    savedStateHandle: SavedStateHandle
) : ViewModel() {
    private val profile = savedStateHandle.toRoute<Profile>()
    private val userInfo: Flow<UserInfo> = userInfoRepository.getUserInfo(profile.id)
}

สุดท้าย คุณสามารถไปยัง Composable โดยใช้ฟังก์ชัน navigate() ได้โดยส่งอินสแตนซ์ของเส้นทาง

navController.navigate(Profile(id = 123))

ซึ่งจะนำผู้ใช้ไปยังcomposable<Profile>ปลายทางใน กราฟการนำทาง อาร์กิวเมนต์การนำทาง เช่น id สามารถรับได้โดย สร้าง Profile ขึ้นใหม่โดยใช้ NavBackStackEntry.toRoute และอ่านพร็อพเพอร์ตี้ของอาร์กิวเมนต์

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