Logik oder Wrapper auf Ziele anwenden

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 ausgedrückt: Sie dekorieren 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 jedes NavEntry in Ihrem Backstack aufgerufen wird. Sie empfängt NavEntry als Parameter. So können Sie Statusobjekte erstellen, die auf den contentKey des Eintrags abgestimmt sind. Mit CompositionLocalProvider kö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 sollten entry.Content() immer in dieser Methode aufrufen.
  • onPop: Ein Callback, der aufgerufen wird, wenn ein NavEntry aus dem Backstack entfernt wurde und die Komposition verlassen hat. Sie erhält die contentKey des entfernten Eintrags. Verwenden Sie die contentKey, 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. Eine Beispielimplementierung finden Sie im Quellcode für rememberSaveableStateHolderNavEntryDecorator. Dadurch wird der Status – ein SaveableStateHolder – erstellt und zum Erstellen des Decorators verwendet.

Backstack dekorieren

Nachdem Sie Ihre NavEntryDecorator erstellt haben, können Sie die Einträge in Ihrem Backstack auf zwei Arten dekorieren:

  • Verwende rememberDecoratedNavEntries. Diese Funktion ist nützlich, wenn Sie mehrere Backstacks mit jeweils eigenen Dekoratoren haben (weitere Informationen finden Sie in diesem Codebeispiel). Die Funktion gibt eine dekorierte Liste von NavEntry zurück, die Sie mit NavDisplay verwenden können.
  • Stellen Sie Ihren Decorator direkt für NavDisplay bereit, indem Sie den Parameter entryDecorators verwenden. NavDisplay ruft rememberDecoratedNavEntries im 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 Decorator keine 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() }
    ),
    // ...
)

Wann sollte ein Dekorator verwendet werden?

Mit einem Decorator können Sie:

  • Erstellen Sie für jedes NavEntry in einem Backstack eine Abhängigkeit. Mit ViewModelStoreNavEntryDecorator wird beispielsweise für jede NavEntry ein ViewModelStore erstellt.
  • Ein Objekt mehreren NavEntrys zuweisen. So können Sie beispielsweise ein ViewModel für mehrere Einträge freigeben.
  • Führen Sie dieselbe Aktion für mehrere NavEntry aus. 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 NavEntry verknüpften Zustand. Wenn beispielsweise ein Eintrag aus dem Backstack entfernt wird, löscht ViewModelStoreNavEntryDecorator die zugehörige ViewModelStore.

Verwenden Sie keinen Decorator für Folgendes:

  • Übergeben Sie eine Abhängigkeit an ein einzelnes NavEntry.
  • Stellen Sie Abhängigkeiten bereit, deren Bereich größer 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.