Mit der Klasse NavEntryDecorator können Sie zusätzliche Informationen angeben oder dieselbe Logik auf Ziele anwenden. Diese Klasse umschließt jedes NavEntry in einem Backstack mit einer zusammensetzbaren Funktion. Anders gesagt: Sie gestaltet den Inhalt des Eintrags.
Benutzerdefinierten Dekorator erstellen
Wenn Sie einen Decorator erstellen möchten, erweitern Sie die Klasse NavEntryDecorator und überschreiben Sie die folgenden Methoden:
decorate: Eine zusammensetzbare Lambda-Funktion, die für jedesNavEntryin Ihrem Backstack aufgerufen wird. Es empfängtNavEntryals Parameter. So können Sie Statusobjekte erstellen, die auf dencontentKeydes Eintrags basieren. MitCompositionLocalProviderkönnen Sie Abhängigkeiten für den Inhalt des Eintrags angeben. Sie können den Inhalt auch in eine zusammensetzbare Funktion einfügen oder Nebeneffekte auslösen. Sie solltenentry.Content()immer in dieser Methode aufrufen.onPop: Ein Callback, der aufgerufen wird, wenn einNavEntryaus dem Backstack entfernt wurde und die Komposition verlassen hat. Sie erhält diecontentKeydes entfernten Eintrags. Verwenden Sie diecontentKey, um den mit diesem Eintrag verknüpften Status zu identifizieren und zu bereinigen.
Im folgenden Beispiel wird die Klasse NavEntryDecorator erweitert, um einen benutzerdefinierten Dekorator 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 Dekorator Zugriff auf den Status benötigt, erstellen Sie eine komponierbare Funktion, die diesen Status erstellt, und verwenden Sie ihn dann, um den Dekorator zu erstellen. Ein Beispiel für die Implementierung finden Sie im Quellcode für rememberSaveableStateHolderNavEntryDecorator. Dadurch wird der Status – ein SaveableStateHolder – erstellt und zum Erstellen des Decorators verwendet.
Backstack dekorieren
Nachdem Sie NavEntryDecorator erstellt haben, können Sie die Einträge in Ihrem Backstack auf zwei Arten dekorieren:
- Verwenden Sie
rememberDecoratedNavEntries. Diese Funktion ist nützlich, wenn Sie mehrere Backstacks mit jeweils eigenen Dekoratoren haben (siehe dieses Codebeispiel). Die Funktion gibt eine dekorierte Liste vonNavEntryzurück, die Sie mitNavDisplayverwenden können. - Stellen Sie Ihren Decorator direkt für
NavDisplaybereit, indem Sie den ParameterentryDecoratorsverwenden.NavDisplayruftrememberDecoratedNavEntriesim Hintergrund auf und zeigt die dekorierten Einträge an.
Standard-Decorator einfügen
Navigation 3 enthält einen Standard-Decorator namens SaveableStateHolderNavEntryDecorator, mit dem der Status eines NavEntry bei Konfigurationsänderungen und Prozessbeendigung beibehalten werden kann. Es umschließt NavEntry-Inhalte mit einem SaveableStateProvider, wodurch rememberSaveable-Aufrufe innerhalb der NavEntry-Inhalte korrekt funktionieren.
Sofern Ihr Dekorator keine SaveableStateProvider bereitstellt, sollten Sie SaveableStateHolderNavEntryDecorator als ersten Dekorator in die Liste der bereitgestellten Dekoratoren 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 mit ResultEventBusNavEntryDecorator jedem NavEntry über die lokale Komposition LocalResultEventBus eine ResultEventBus bereitstellen.
Standardmäßig erstellt und speichert rememberResultEventBusNavEntryDecorator intern eine eigene ResultEventBus-Instanz mit rememberResultEventBus. Wenn Sie außerhalb der Dekoratorhierarchie (z. B. im App-Scaffolding auf oberster Ebene) auf den Ereignisbus zugreifen müssen, können Sie ResultEventBus durch Aufrufen von rememberResultEventBus und Übergeben an rememberResultEventBusNavEntryDecorator(resultEventBus) hochziehen:
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 Dekorator verwendet werden?
Mit einem Decorator können Sie:
- Erstellen Sie für jedes
NavEntryin einem Backstack eine Abhängigkeit. MitViewModelStoreNavEntryDecoratorwird beispielsweise für jedeNavEntryeinViewModelStoreerstellt. - Ergebnisse übergeben und zwischen Zielen kommunizieren. Beispielsweise bietet
ResultEventBusNavEntryDecoratoreinenResultEventBusfür Ziele im Backstack. - Ein Objekt mehreren
NavEntrys zuweisen. So können Sie beispielsweise einViewModelfür mehrere Einträge freigeben. - Führen Sie dieselbe Aktion für mehrere
NavEntryaus. Sie können beispielsweise für jeden Eintrag Protokollierungs-, Debugging- oder Tracing-Vorgänge ausführen. - Umschließe
NavEntrys mit derselben zusammensetzbaren Funktion. - Bereinigen Sie den mit
NavEntrys verknüpften Status. Wenn beispielsweise ein Eintrag aus dem Backstack entfernt wird, löschtViewModelStoreNavEntryDecoratordie zugehörigeViewModelStore.
Verwenden Sie keinen Decorator für Folgendes:
- Eine Abhängigkeit an ein einzelnes
NavEntryübergeben. - Stellen Sie Abhängigkeiten bereit, deren Bereich breiter als der Backstack ist.
In beiden Fällen sollten Sie die Abhängigkeit direkt beim Erstellen von NavEntry übergeben.
Weitere Codebeispiele finden Sie unter NavEntryDecorator.