Mit der Klasse NavEntryDecorator können Sie zusätzliche Informationen angeben oder dieselbe Logik auf Ziele anwenden. Diese Klasse umschließt jeden NavEntry in einem Back Stack mit einer zusammensetzbaren Funktion. Anders ausgedrückt: Der Inhalt des Eintrags wird dekoriert.
Benutzerdefinierten Decorator erstellen
Wenn Sie einen Decorator erstellen möchten, erweitern Sie die Klasse NavEntryDecorator und überschreiben Sie die folgenden Methoden:
decorate: Ein zusammensetzbares Lambda, das für jedenNavEntryim Back Stack aufgerufen wird. Sie empfängt dieNavEntryals Parameter. So können Sie Zustandsobjekte erstellen, die demcontentKeydes Eintrags zugeordnet sind. MitCompositionLocalProviderkönnen Sie Abhängigkeiten für den Inhalt des Eintrags bereitstellen. Sie können den Inhalt auch mit einer zusammensetzbaren Funktion umschließen oder Nebenwirkungen auslösen. Sie solltenentry.Content()immer innerhalb dieser Methode aufrufen.onPop: Ein Callback, der aufgerufen wird, wenn einNavEntryaus dem Back Stack entfernt wurde und die Komposition verlassen hat. Sie empfängt dencontentKeydes entfernten Eintrags. Verwenden Sie diecontentKey, um alle mit diesem Eintrag verknüpften Status zu identifizieren und zu bereinigen.
Im folgenden Beispiel wird die Klasse NavEntryDecorator erweitert, um einen benutzerdefinierten Decorator zu erstellen.
// 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") } )
Wenn Ihr Decorator Zugriff auf den Status benötigt, erstellen Sie eine zusammensetzbare Funktion, die diesen Status erstellt, und verwenden Sie sie dann, um den Decorator zu erstellen. Ein Beispiel für eine Implementierung finden Sie im Quellcode für rememberSaveableStateHolderNavEntryDecorator. Dadurch wird der Status (ein SaveableStateHolder) erstellt und zum Erstellen des Decorators verwendet.
Back Stack dekorieren
Nachdem Sie den NavEntryDecorator erstellt haben, können Sie die Einträge im Back Stack auf zwei Arten dekorieren:
- Verwenden Sie
rememberDecoratedNavEntries. Diese Funktion ist nützlich, wenn Sie mehrere Back Stacks haben, die jeweils eigene Decorators haben. Weitere Informationen finden Sie in diesem Code-Rezept. Die Funktion gibt eine dekorierte Liste vonNavEntrys zurück, die Sie mitNavDisplayverwenden können. - Geben Sie Ihren Decorator mit dem Parameter
entryDecoratorsdirekt anNavDisplayweiter.NavDisplayruft im HintergrundrememberDecoratedNavEntriesauf und zeigt die dekorierten Einträge an.
Standard-Decorator einbeziehen
Navigation 3 enthält einen Standard-Decorator namens SaveableStateHolderNavEntryDecorator, mit dem der Status eines NavEntry bei Konfigurationsänderungen und Prozessbeendigungen beibehalten werden kann. Sie umschließt NavEntry-Inhalte mit einem SaveableStateProvider, sodass rememberSaveable-Aufrufe innerhalb des NavEntry-Inhalts korrekt funktionieren.
Sofern Ihr Decorator keinen SaveableStateProvider bereitstellt, sollten Sie SaveableStateHolderNavEntryDecorator als ersten Decorator in die Liste der bereitgestellten Decorators aufnehmen. Sie wird mit rememberSaveableStateHolderNavEntryDecorator erstellt.
Beispiel:
// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator NavDisplay( entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), remember { CustomNavEntryDecorator() } ), // ... )
Ergebnisse mit ResultEventBusNavEntryDecorator übergeben
Ab Navigation 3 1.2.0 können Sie ResultEventBusNavEntryDecorator verwenden, um jedem NavEntry einen ResultEventBus mit der CompositionLocal LocalResultEventBus bereitzustellen.
Standardmäßig erstellt rememberResultEventBusNavEntryDecorator eine eigene ResultEventBus-Instanz und speichert sie intern mit rememberResultEventBus. Wenn Sie außerhalb der Decorator-Hierarchie auf den Event Bus zugreifen müssen (z. B. auf der obersten Ebene des App-Gerüsts), können Sie den ResultEventBus hochstufen, indem Sie rememberResultEventBus aufrufen und an rememberResultEventBusNavEntryDecorator(resultEventBus) übergeben:
val resultEventBus = rememberResultEventBus() NavDisplay( /* ... */ entryDecorators = listOf( rememberSaveableStateHolderNavEntryDecorator(), rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus) ) )
Weitere Informationen zum Senden und Beobachten von Ergebnissen finden Sie unter Ergebnisse zurückgeben.
Wann sollte ein Decorator verwendet werden?
Mit einem Decorator können Sie Folgendes tun:
- Erstellen Sie für jedes
NavEntryin einem Back Stack eine Abhängigkeit. Beispiel:ViewModelStoreNavEntryDecoratorerstellt für jedeNavEntryeineViewModelStore. - Ergebnisse weitergeben und zwischen Zielen kommunizieren. Beispielsweise bietet die
ResultEventBusNavEntryDecoratoreinenResultEventBuszu Zielen im Back Stack. - Ein Objekt auf mehrere
NavEntrys beschränken. Beispiel: Um einenViewModelzwischen mehreren Einträgen zu teilen. - Führen Sie dieselbe Aktion für mehrere
NavEntrys aus. Beispielsweise, um Logging-, Debugging- oder Tracing-Vorgänge für jeden Eintrag auszuführen. NavEntrys mit derselben zusammensetzbaren Funktion umschließen.- Bereinigen Sie den mit
NavEntrys verknüpften Status. Wenn beispielsweise ein Eintrag aus dem Back Stack entfernt wird, löscht derViewModelStoreNavEntryDecoratordie zugehörigeViewModelStore.
Verwenden Sie keinen Decorator für Folgendes:
- Übergeben Sie eine Abhängigkeit an eine einzelne
NavEntry. - Abhängigkeiten bereitstellen, deren Bereich größer als der Back Stack ist.
In beiden Fällen übergeben Sie die Abhängigkeit stattdessen direkt beim Erstellen des NavEntry.
Weitere Codebeispiele finden Sie unter NavEntryDecorator.