Lưu và quản lý trạng thái điều hướng

Các phần sau đây mô tả các chiến lược để lưu ngăn xếp lui và lưu trữ trạng thái liên kết với các mục trên ngăn xếp lui.

Lưu ngăn xếp lui

Việc đảm bảo trạng thái điều hướng của ứng dụng vẫn tồn tại trong nhiều sự kiện trong vòng đời, bao gồm cả thay đổi về cấu hình và quá trình bị gián đoạn, là điều rất quan trọng để mang lại trải nghiệm tốt cho người dùng. Trong Navigation 3, bạn sở hữu ngăn xếp lui, vì vậy, không có nguyên tắc nghiêm ngặt nào về cách bạn nên tạo hoặc lưu ngăn xếp lui. Tuy nhiên, Navigation 3 cung cấp một phương thức thuận tiện để cung cấp cho bạn một ngăn xếp lui có thể lưu: rememberNavBackStack.

Sử dụng rememberNavBackStack

Hàm có khả năng kết hợp rememberNavBackStack được thiết kế để tạo một ngăn xếp lui vẫn tồn tại trong các thay đổi về cấu hình và khi quá trình bị gián đoạn.

Để rememberNavBackStack hoạt động chính xác, mỗi khoá trong ngăn xếp lui phải tuân thủ các yêu cầu cụ thể:

  • Triển khai giao diện NavKey: Mọi khoá trong ngăn xếp lui phải triển khai giao diện NavKey. Đây đóng vai trò là giao diện điểm đánh dấu, báo hiệu cho thư viện rằng có thể lưu khoá.
  • Có chú thích @Serializable: Ngoài việc triển khai NavKey, các lớp và đối tượng chính của bạn phải được đánh dấu bằng chú thích @Serializable.

Đoạn mã sau đây cho thấy cách triển khai chính xác rememberNavBackStack:

@Serializable
data object Home : NavKey

@Composable
fun NavBackStack() {
    val backStack = rememberNavBackStack(Home)
}

Phương án thay thế: Lưu trữ trong ViewModel

Một phương pháp khác để quản lý ngăn xếp lui là lưu trữ ngăn xếp đó trong ViewModel. Để duy trì hoạt động sau khi bị buộc tắt khi sử dụng ViewModel hoặc bất kỳ bộ nhớ tuỳ chỉnh nào khác, bạn cần:

  • Đảm bảo các khoá của bạn có thể chuyển đổi tuần tự: Giống như với rememberNavBackStack, các khoá điều hướng của bạn phải có thể chuyển đổi tuần tự.
  • Xử lý quá trình chuyển đổi tuần tự và huỷ chuyển đổi tuần tự theo cách thủ công: Bạn có trách nhiệm lưu trữ thủ công bản trình bày chuyển đổi tuần tự của từng khoá vào và huỷ chuyển đổi tuần tự từ bộ nhớ cố định (ví dụ: SharedPreferences, cơ sở dữ liệu hoặc tệp) khi ứng dụng của bạn chuyển sang chế độ nền hoặc đang được khôi phục.

Đặt phạm vi ViewModel thành NavEntry

ViewModels được dùng để giữ lại trạng thái liên quan đến giao diện người dùng trong các thay đổi về cấu hình, chẳng hạn như xoay màn hình. Theo mặc định, ViewModels được đặt trong phạm vi của ViewModelStoreOwner gần nhất, thường là Activity hoặc Fragment.

Tuy nhiên, bạn có thể muốn đặt phạm vi ViewModel thành một NavEntry cụ thể (tức là một màn hình hoặc đích đến cụ thể) trên ngăn xếp lui, thay vì toàn bộ Activity. Điều này đảm bảo rằng trạng thái của ViewModel chỉ được giữ lại trong khi NavEntry cụ thể đó là một phần của ngăn xếp lui và bị xoá khi NavEntry được đẩy ra.

Thư viện bổ trợ androidx.lifecycle:lifecycle-viewmodel-navigation3 cung cấp một NavEntryDecorator hỗ trợ việc này. Phương thức trang trí này cung cấp một ViewModelStoreOwner cho mỗi NavEntry. Khi bạn tạo ViewModel bên trong nội dung của NavEntry (ví dụ: sử dụng viewModel() trong Compose), ViewModel sẽ tự động được đưa vào phạm vi của khoá NavEntry cụ thể đó trên ngăn xếp lui. Điều này có nghĩa là ViewModel được tạo khi NavEntry được thêm vào ngăn xếp lui và được xoá khi ngăn xếp lui bị xoá.

Để sử dụng NavEntryDecorator nhằm xác định phạm vi của ViewModel cho NavEntry, hãy làm theo các bước sau:

  1. Thêm phần phụ thuộc androidx.lifecycle:lifecycle-viewmodel-navigation3 vào tệp app/build.gradle.kts.
  2. Thêm rememberSavedStateNavEntryDecorator() vào danh sách entryDecorators khi tạo NavDisplay.
  3. Thêm các trình trang trí khác vào NavDisplay.

NavDisplay(
    entryDecorators = listOf(
        // Add the default decorators for managing scenes and saving state
        rememberSceneSetupNavEntryDecorator(),
        rememberSavedStateNavEntryDecorator(),
        // Then add the view model store decorator
        rememberViewModelStoreNavEntryDecorator()
    ),
    backStack = backStack,
    entryProvider = entryProvider { },
)