An toàn về kiểu trong DSL Kotlin và Navigation Compose

Bạn có thể sử dụng các API an toàn về kiểu tích hợp để cung cấp chế độ an toàn về kiểu vào thời gian biên dịch cho biểu đồ điều hướng. Các API này có sẵn khi ứng dụng của bạn dùng Navigation Compose hoặc Navigation Kotlin DSL. Các tính năng này sẽ ra mắt từ ngày Navigation 2.8.0.

Các API này tương đương với những gì Safe Args cung cấp cho biểu đồ điều hướng được tạo bằng XML.

Xác định các tuyến đường

Để sử dụng các tuyến an toàn về kiểu trong Compose, trước tiên, bạn cần xác định các lớp hoặc đối tượng có thể chuyển đổi tuần tự đại diện cho các tuyến của mình.

Để xác định các đối tượng có thể chuyển đổi tuần tự, hãy sử dụng chú thích @Serializable do trình bổ trợ Chuyển đổi tuần tự Kotlin cung cấp. Bạn có thể thêm trình bổ trợ này vào dự án bằng cách thêm các phần phụ thuộc này.

Hãy sử dụng các quy tắc sau để quyết định loại đường nào bạn nên sử dụng:

  • Object: Sử dụng một đối tượng cho các tuyến đường không có đối số.
  • Lớp: Sử dụng một lớp hoặc lớp dữ liệu cho các tuyến có đối số.
  • KClass<T>: Sử dụng nếu bạn không cần truyền đối số, chẳng hạn như một lớp không có tham số hoặc một lớp mà tất cả các tham số đều có giá trị mặc định
    1. Ví dụ: Profile::class

Trong mọi trường hợp, đối tượng hoặc lớp phải có thể chuyển đổi tuần tự.

Ví dụ:

// 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)

Tạo biểu đồ

Tiếp theo, bạn cần xác định biểu đồ điều hướng. Sử dụng hàm composable() để xác định các thành phần kết hợp làm đích đến trong biểu đồ điều hướng.

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

Hãy quan sát những điều sau trong ví dụ này:

  • composable() lấy một tham số kiểu. Tức là composable<Profile>.
  • Xác định loại đích đến là một phương pháp mạnh mẽ hơn so với việc truyền một route chuỗi như trong composable("profile").
  • Lớp tuyến đường xác định loại của từng đối số điều hướng, như trong val id: String, nên không cần NavArgument.
  • Đối với tuyến đường hồ sơ, phương thức mở rộng toRoute() sẽ tạo lại đối tượng Profile từ NavBackStackEntry và các đối số của đối tượng đó.

Để biết thêm thông tin về cách thiết kế biểu đồ nói chung, hãy xem trang Thiết kế biểu đồ điều hướng.

Truy cập vào các đối số trong ViewModel

Để truy cập vào các đối số từ một tuyến đường an toàn về kiểu trong ViewModel, bạn có thể truy xuất tuyến đường từ SavedStateHandle bằng cách gọi SavedStateHandle.toRoute<T>(), trong đó T là lớp tuyến đường của bạn:

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

Cuối cùng, bạn có thể chuyển đến thành phần kết hợp bằng cách sử dụng hàm navigate() bằng cách truyền vào thực thể của tuyến đường:

navController.navigate(Profile(id = 123))

Thao tác này sẽ điều hướng người dùng đến đích composable<Profile> trong biểu đồ điều hướng. Bạn có thể lấy mọi đối số điều hướng, chẳng hạn như id, bằng cách tạo lại Profile bằng NavBackStackEntry.toRoute và đọc các thuộc tính của đối số đó.

Tài nguyên khác