Możesz podać dodatkowe informacje lub zastosować tę samą logikę do miejsc docelowych, używając klasy NavEntryDecorator. Ta klasa opakowuje każdy element NavEntry w stosie wstecznym za pomocą funkcji kompozycyjnej. Innymi słowy, wzbogaca treść wpisu.
Tworzenie dekoratora niestandardowego
Aby utworzyć dekorator, rozszerz klasę NavEntryDecorator i zastąp te metody:
decorate– funkcja lambda, którą można komponować i która jest wywoływana dla każdego elementuNavEntryna stosie wstecznym. Otrzymuje on parametrNavEntry. Umożliwia to tworzenie obiektów stanu, które są powiązane z atrybutemcontentKeywpisu. Możesz użyćCompositionLocalProvider, aby podać zależności od treści wpisu. Możesz też otoczyć treść funkcją typu „composable” lub wywołać efekty uboczne. W tej metodzie zawsze należy wywoływać funkcjęentry.Content().onPop– wywołanie zwrotne, które jest wywoływane, gdy elementNavEntryzostał usunięty z listy wstecznej i został usunięty z kompozycji. OtrzymujecontentKeyusuniętego wpisu. UżyjcontentKey, aby zidentyfikować i usunąć wszelkie stany powiązane z tym wpisem.
W przykładzie poniżej rozszerzamy klasę NavEntryDecorator, aby utworzyć dekorator niestandardowy.
// 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") } )
Jeśli dekorator potrzebuje dostępu do stanu, utwórz funkcję typu „composable”, która tworzy ten stan, a następnie użyj jej do utworzenia dekoratora. Przykładową implementację znajdziesz w kodzie źródłowym rememberSaveableStateHolderNavEntryDecorator. Spowoduje to utworzenie stanu – SaveableStateHolder – i użycie go do utworzenia dekoratora.
Dekorowanie stosu wstecznego
Po utworzeniu NavEntryDecorator możesz ozdobić wpisy na liście wstecznej na 2 sposoby:
- Użyj
rememberDecoratedNavEntries. Ta funkcja jest przydatna, gdy masz kilka stosów wstecznych, z których każdy ma własny zestaw dekoratorów (więcej informacji znajdziesz w tym przepisie na kod). Funkcja zwraca udekorowaną listę elementów typuNavEntry, których możesz używać z funkcjąNavDisplay. - Podaj dekorator bezpośrednio do
NavDisplayza pomocą parametruentryDecorators.NavDisplaywywołujerememberDecoratedNavEntriesw tle i wyświetla zmodyfikowane wpisy.
Uwzględnij domyślny dekorator
Biblioteka Navigation 3 zawiera domyślny dekorator o nazwie SaveableStateHolderNavEntryDecorator, który umożliwia zachowanie stanu elementu NavEntry po zmianach konfiguracji i śmierci procesu. Obejmuje ona treści NavEntry tagiem SaveableStateProvider, co umożliwia prawidłowe działanie wywołań rememberSaveable w treściach NavEntry.
Jeśli dekorator nie zapewnia SaveableStateProvider, jako pierwszy dekorator na liście dostarczonych dekoratorów należy umieścić SaveableStateHolderNavEntryDecorator. Jest on tworzony za pomocąrememberSaveableStateHolderNavEntryDecorator.
Przykład:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Przekazywanie wyników za pomocą ResultEventBusNavEntryDecorator
Od wersji 1.2.0 biblioteki Navigation 3 możesz używać funkcji
ResultEventBusNavEntryDecorator, aby przekazywać
ResultEventBus do każdego elementu NavEntry za pomocą lokalnej kompozycji
LocalResultEventBus.
Domyślnie rememberResultEventBusNavEntryDecorator tworzy i zapamiętuje własną instancję ResultEventBus wewnętrznie za pomocą rememberResultEventBus. Jeśli musisz uzyskać dostęp do magistrali zdarzeń poza hierarchią dekoratorów (np. w szkielecie aplikacji najwyższego poziomu), możesz przenieść ResultEventBus, wywołując rememberResultEventBus i przekazując je do rememberResultEventBusNavEntryDecorator(resultEventBus):
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Więcej informacji o wysyłaniu i obserwowaniu wyników znajdziesz w sekcji Zwracanie wyników.
Kiedy używać dekoratora
Za pomocą dekoratora możesz:
- Utwórz zależność dla każdego elementu
NavEntryw stosie wstecznym. Na przykład znakViewModelStoreNavEntryDecoratortworzy znakViewModelStoredla każdego znakuNavEntry. - Przekazywanie wyników i komunikacja między miejscami docelowymi. Na przykład
ResultEventBusNavEntryDecoratorzapewniaResultEventBusdo miejsc docelowych w stosie wstecznym. - Określ zakres obiektu dla wielu
NavEntry. Na przykład, aby udostępnićViewModelmiędzy wieloma wpisami. - Wykonaj to samo działanie w przypadku wielu
NavEntry. Na przykład do wykonywania operacji logowania, debugowania lub śledzenia dla każdego wpisu. - Owiń
NavEntrys tą samą funkcją typu „composable”. - Zwalnianie miejsca powiązanego z
NavEntry. Jeśli np. wpis zostanie usunięty z listy wstecznej, elementViewModelStoreNavEntryDecoratorwyczyści powiązany z nim elementViewModelStore.
Nie używaj dekoratora do:
- Przekazywanie zależności do pojedynczego elementu
NavEntry. - Zapewnij zależności, których zakres jest szerszy niż stos wsteczny.
W obu tych przypadkach przekaż zależność bezpośrednio podczas tworzenia NavEntry.
Więcej przykładów kodu znajdziesz w NavEntryDecorator.