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ỗiNavEntrytrong ngăn xếp lui. Phương thức này nhậnNavEntrylà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á theocontentKeycủa mục nhập. Bạn có thể dùngCompositionLocalProviderđể 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ọientry.Content()trong phương thức này.onPop– Một lệnh gọi lại được gọi khiNavEntryđã bị xoá khỏi ngăn xếp lui và đã rời khỏi thành phần. Nó nhận đượccontentKeycủa mục đã xoá. Sử dụngcontentKeyđể 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ácNavEntrymà bạn có thể dùng vớiNavDisplay. - Cung cấp trình trang trí của bạn trực tiếp cho
NavDisplaybằng cách sử dụng tham sốentryDecorators.NavDisplaygọirememberDecoratedNavEntriestheo 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
NavEntrytrong ngăn xếp quay lại. Ví dụ:ViewModelStoreNavEntryDecoratorsẽ tạo mộtViewModelStorecho mọiNavEntry. - Phạm vi một đối tượng cho nhiều
NavEntry. Ví dụ: để chia sẻ mộtViewModelgiữ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
NavEntrybằ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,ViewModelStoreNavEntryDecoratorsẽ 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
NavEntryduy 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.