Áp dụng logic hoặc trình bao bọc cho đích đến

Bạn có thể cung cấp thêm thông tin hoặc áp dụng cùng một logic cho các đích đến bằng cách sử dụng lớp NavEntryDecorator. Lớp này bao bọc từng NavEntry trong một ngăn xếp lui bằng một hàm có khả năng kết hợp. Nói cách khác, nó trang trí nội dung của mục nhập.

Tạo một đối tượng trang trí tuỳ chỉnh

Để tạo một đối tượng trang trí, hãy mở rộng lớp NavEntryDecorator và ghi đè các phương thức sau:

  • decorate – Một hàm lambda có thể kết hợp được gọi cho mỗi NavEntry trong ngăn xếp lui. Phương thức này nhận NavEntry làm tham số. Điều này cho phép bạn tạo các đối tượng trạng thái được khoá theo contentKey của mục nhập. Bạn có thể dùng CompositionLocalProvider để cung cấp các phần phụ thuộc cho nội dung của mục nhập. Bạn cũng có thể bao quanh nội dung bằng một hàm có khả năng kết hợp hoặc kích hoạt các hiệu ứng phụ. Bạn phải luôn gọi entry.Content() trong phương thức này.
  • onPop – Một lệnh gọi lại được gọi khi NavEntry đã bị xoá khỏi ngăn xếp lui và đã rời khỏi thành phần. Nó nhận được contentKey của mục đã xoá. Sử dụng contentKey để xác định và dọn dẹp mọi trạng thái liên kết với mục đó.

Ví dụ sau đây mở rộng lớp NavEntryDecorator để tạo một trình trang trí tuỳ chỉnh.

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

Nếu đối tượng trang trí của bạn cần quyền truy cập vào trạng thái, hãy tạo một hàm có khả năng kết hợp tạo trạng thái đó rồi dùng hàm đó để tạo đối tượng trang trí. Để biết ví dụ về cách triển khai, hãy xem mã nguồn của rememberSaveableStateHolderNavEntryDecorator. Thao tác này sẽ tạo trạng thái (một SaveableStateHolder) và dùng trạng thái đó để tạo trình trang trí.

Trang trí ngăn xếp lui

Sau khi bạn tạo NavEntryDecorator, hãy trang trí các mục trong ngăn xếp quay lại theo một trong hai cách sau:

  • Sử dụng rememberDecoratedNavEntries. Hàm này hữu ích khi bạn có nhiều ngăn xếp lui, mỗi ngăn xếp có một nhóm đối tượng trang trí riêng (xem công thức mã này để biết thêm thông tin chi tiết). Hàm này trả về một danh sách được trang trí gồm các NavEntry mà bạn có thể dùng với NavDisplay.
  • Cung cấp trình trang trí của bạn trực tiếp cho NavDisplay bằng cách sử dụng tham số entryDecorators. NavDisplay gọi rememberDecoratedNavEntries theo cách không rõ ràng và hiển thị các mục được trang trí.

Thêm trình trang trí mặc định

Navigation 3 có một đối tượng trang trí mặc định tên là SaveableStateHolderNavEntryDecorator, cho phép giữ lại trạng thái của NavEntry thông qua các thay đổi về cấu hình và quá trình bị gián đoạn. Thành phần này bao bọc nội dung NavEntry bằng một SaveableStateProvider, cho phép các lệnh gọi rememberSaveable bên trong nội dung NavEntry hoạt động đúng cách.

Trừ phi lớp trang trí của bạn cung cấp một SaveableStateProvider, nếu không, bạn nên thêm SaveableStateHolderNavEntryDecorator làm lớp trang trí đầu tiên trong danh sách các lớp trang trí được cung cấp. Thành phần này được tạo bằng rememberSaveableStateHolderNavEntryDecorator.

Ví dụ:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

Trường hợp sử dụng decorator

Sử dụng một đối tượng trang trí để:

  • Tạo một phần phụ thuộc cho mọi NavEntry trong ngăn xếp quay lại. Ví dụ: ViewModelStoreNavEntryDecorator sẽ tạo một ViewModelStore cho mọi NavEntry.
  • Phạm vi một đối tượng cho nhiều NavEntry. Ví dụ: để chia sẻ một ViewModel giữa nhiều mục.
  • Thực hiện cùng một thao tác cho nhiều NavEntry. Ví dụ: để thực hiện các thao tác ghi nhật ký, gỡ lỗi hoặc theo dõi cho từng mục nhập.
  • Gói NavEntry bằng cùng một hàm có khả năng kết hợp.
  • Dọn dẹp trạng thái liên kết với các NavEntry. Ví dụ: khi một mục nhập bị xoá khỏi ngăn xếp lui, ViewModelStoreNavEntryDecorator sẽ xoá ViewModelStore được liên kết.

Không sử dụng một đối tượng trang trí để:

  • Truyền một phần phụ thuộc đến một NavEntry duy nhất.
  • Cung cấp các phần phụ thuộc có phạm vi rộng hơn ngăn xếp lui.

Trong cả hai trường hợp này, hãy truyền trực tiếp phần phụ thuộc khi tạo NavEntry.

Để xem thêm các đoạn mã ví dụ, hãy xem NavEntryDecorator.