Die Dynamic Navigator-Bibliothek erweitert die Funktionalität des Komponente "Jetpack Navigation" für die Arbeit mit Zielen die in den Funktionsmodule. Diese Bibliothek bietet auch eine nahtlose Installation von On-Demand-Funktionen Module bei der Navigation zu diesen Zielen.
Einrichten
Verwende zur Unterstützung von Funktionsmodulen die folgenden Abhängigkeiten in der Datei build.gradle
deines App-Moduls:
Groovy
dependencies { def nav_version = "2.8.4" api "androidx.navigation:navigation-fragment-ktx:$nav_version" api "androidx.navigation:navigation-ui-ktx:$nav_version" api "androidx.navigation:navigation-dynamic-features-fragment:$nav_version" }
Kotlin
dependencies { val nav_version = "2.8.4" api("androidx.navigation:navigation-fragment-ktx:$nav_version") api("androidx.navigation:navigation-ui-ktx:$nav_version") api("androidx.navigation:navigation-dynamic-features-fragment:$nav_version") }
Für die anderen Navigationsabhängigkeiten müssen API-Konfigurationen verwendet werden. damit sie für Ihre Funktionsmodule zur Verfügung stehen.
Grundlegende Nutzung
Ändern Sie zuerst alle Instanzen von, um Funktionsmodule zu unterstützen.
NavHostFragment
in deiner App, um
androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:navGraph="@navigation/nav_graph"
... />
Fügen Sie als Nächstes jedem <activity>
-, <fragment>
- oderapp:moduleName
<navigation>
Ziele in deinem com.android.dynamic-feature
-Modul
Navigationsgrafiken, die mit DynamicNavHostFragment
verknüpft sind.
Dieses Attribut teilt der Dynamic Navigator-Bibliothek mit,
gehört zu einem Funktionsmodul mit dem von Ihnen angegebenen Namen.
<fragment
app:moduleName="myDynamicFeature"
android:id="@+id/featureFragment"
android:name="com.google.android.samples.feature.FeatureFragment"
... />
Wenn Sie zu einem dieser Ziele navigieren, zeigt die Dynamic Navigator-Bibliothek prüft zuerst, ob das Feature-Modul installiert ist. Wenn die Funktion bereits vorhanden ist, navigiert Ihre App wie erwartet zum Ziel. Wenn das Modul nicht vorhanden ist, zeigt Ihre App ein Zwischenfortschrittsfragment an wenn das Modul installiert wird. Die Standardimplementierung des Das Fortschrittsfragment zeigt eine einfache Benutzeroberfläche mit einer Fortschrittsanzeige und verarbeitet beliebige Installationsfehler.
<ph type="x-smartling-placeholder">Zum Anpassen dieser UI oder zur manuellen Ausführung der Installation App-Bildschirm sehen, sehen Sie Passen Sie das Fortschrittsfragment an und Überwachen Sie den Anfragestatus in diesem Thema.
Ziele, für die „app:moduleName
“ nicht angegeben ist, funktionieren weiterhin ohne
ändert sich und verhalten sich so, als ob Ihre Anwendung ein reguläres NavHostFragment
verwendet.
Fortschrittsfragment anpassen
Du kannst die Implementierung des Fortschrittsfragments für jede Navigationsgrafik überschreiben
indem Sie das Attribut app:progressDestination
auf die ID des Ziels festlegen
die Sie für den Installationsfortschritt verwenden möchten. Ihr individueller Fortschritt
Ziel sollte ein
Fragment
, die abgeleitet aus
AbstractProgressFragment
Sie müssen die abstrakten Methoden für Benachrichtigungen zur Installation überschreiben
Fortschritt, Fehler und andere Ereignisse. Sie können sich den Installationsstatus dann in einem
UI Ihrer Wahl.
Die Standardimplementierung
DefaultProgressFragment
-Klasse verwendet diese API, um den Installationsfortschritt anzuzeigen.
Anfragestatus überwachen
Mit der Dynamic Navigator-Bibliothek können Sie einen UX-Ablauf implementieren, der dem eins in UX-Best Practices für die On-Demand-Bereitstellung bei denen Nutzende im Kontext eines vorherigen Bildschirms bleiben, während sie auf um die Installation abzuschließen. Das bedeutet, dass Sie keine Zwischenschritte UI- oder Fortschrittsfragment.
<ph type="x-smartling-placeholder">In diesem Szenario sind Sie für Überwachung und Verarbeitung aller Installationsstatus, Fortschrittsänderungen, Fehler so weiter.
Um diesen nicht blockierenden Navigationsfluss zu starten, übergeben Sie einen
DynamicExtras
Objekt, das ein
DynamicInstallMonitor
bis
NavController.navigate()
,
Dies wird im folgenden Beispiel gezeigt:
Kotlin
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) )
Java
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); )
Unmittelbar nach dem Aufruf von navigate()
sollten Sie den Wert von
installMonitor.isInstallRequired
, um zu sehen, ob die gewünschte Navigation ausfiel
der Installation eines Feature-Moduls.
- Wenn der Wert
false
lautet, ist die Navigation zu einem normalen Ziel irgendetwas anderes tun müssen. Wenn der Wert
true
ist, sollten Sie dasLiveData
-Objekt beobachten, das ist jetzt ininstallMonitor.status
. DiesesLiveData
-Objekt sendetSplitInstallSessionState
aus der Play Core-Bibliothek. Diese Updates enthalten Installationen Fortschrittsereignisse, mit denen Sie die Benutzeroberfläche aktualisieren können. Denken Sie daran, alle relevanten Status, wie in den Play-Hauptleitfaden einschließlich Nutzerbestätigung anfordern wenn nötig.Kotlin
val navController = ... val installMonitor = DynamicInstallMonitor() navController.navigate( destinationId, null, null, DynamicExtras(installMonitor) ) if (installMonitor.isInstallRequired) { installMonitor.status.observe(this, object : Observer<SplitInstallSessionState> { override fun onChanged(sessionState: SplitInstallSessionState) { when (sessionState.status()) { SplitInstallSessionStatus.INSTALLED -> { // Call navigate again here or after user taps again in the UI: // navController.navigate(destinationId, destinationArgs, null, null) } SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> { SplitInstallManager.startConfirmationDialogForResult(...) } // Handle all remaining states: SplitInstallSessionStatus.FAILED -> {} SplitInstallSessionStatus.CANCELED -> {} } if (sessionState.hasTerminalStatus()) { installMonitor.status.removeObserver(this); } } }); }
Java
NavController navController = ... DynamicInstallMonitor installMonitor = new DynamicInstallMonitor(); navController.navigate( destinationId, null, null, new DynamicExtras(installMonitor); ) if (installMonitor.isInstallRequired()) { installMonitor.getStatus().observe(this, new Observer<SplitInstallSessionState>() { @Override public void onChanged(SplitInstallSessionState sessionState) { switch (sessionState.status()) { case SplitInstallSessionStatus.INSTALLED: // Call navigate again here or after user taps again in the UI: // navController.navigate(mDestinationId, mDestinationArgs, null, null); break; case SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION: SplitInstallManager.startConfirmationDialogForResult(...) break; // Handle all remaining states: case SplitInstallSessionStatus.FAILED: break; case SplitInstallSessionStatus.CANCELED: break; } if (sessionState.hasTerminalStatus()) { installMonitor.getStatus().removeObserver(this); } } }); }
Wenn die Installation abgeschlossen ist, gibt das Objekt LiveData
eine Meldung aus:
SplitInstallSessionStatus.INSTALLED
-Status. Rufen Sie dann
Noch einmal NavController.navigate()
. Da das Modul jetzt installiert ist, wird der Aufruf
erfolgreich ist und die App wie erwartet zum Ziel navigiert.
Nach Erreichen des Endzustands, etwa nach Abschluss der Installation
die Installation fehlschlägt, sollten Sie den LiveData
-Beobachter entfernen, um Arbeitsspeicher zu vermeiden.
Lecks. Sie können prüfen, ob der Status einen Endzustand darstellt, indem Sie
SplitInstallSessionStatus.hasTerminalStatus()
Weitere Informationen finden Sie unter AbstractProgressFragment
.
finden Sie eine Beispielimplementierung dieses Beobachters.
Enthaltene Grafiken
Die Bibliothek „Dynamic Navigator“ unterstützt das Einfügen von Grafiken, die in Funktionsmodule. Um ein Diagramm einzufügen, das in einem Element definiert ist, -Modul, gehen Sie so vor:
Verwenden Sie
<include-dynamic/>
anstelle von<include/>
, wie im Folgenden gezeigt. Beispiel:<include-dynamic android:id="@+id/includedGraph" app:moduleName="includedgraphfeature" app:graphResName="included_feature_nav" app:graphPackage="com.google.android.samples.dynamic_navigator.included_graph_feature" />
Innerhalb von
<include-dynamic ... />
müssen Sie die folgenden Attribute angeben:app:graphResName
: der Name der Navigationsgrafikressource. Die name wird aus dem Dateinamen der Grafik abgeleitet. Befindet sich das Diagramm beispielsweiseres/navigation/nav_graph.xml
lautet der Ressourcennamenav_graph
.android:id
ist die Ziel-ID des Diagramms. Bibliothek für Dynamic Navigator ignoriert alleandroid:id
-Werte, die im Stammelement der enthaltene Grafik.app:moduleName
: der Paketname des Moduls.
Das richtige GraphPackage verwenden
Es ist wichtig, dass die app:graphPackage
korrekt ist, da die Navigation
Komponente kann das angegebene Element (navGraph
) nicht enthalten
Modul, andernfalls.
Der Paketname eines dynamischen Funktionsmoduls wird durch Anhängen des
Name des Moduls in die applicationId
des Basis-App-Moduls. Wenn also
Das Basis-App-Modul hat einen applicationId
von com.example.dynamicfeatureapp
und
den Namen des dynamischen Funktionsmoduls DynamicFeatureModule
hat, dann
wird der Name des dynamischen Moduls
com.example.dynamicfeatureapp.DynamicFeatureModule
. Dieser Paketname ist
Groß- und Kleinschreibung
berücksichtigen.
Im Zweifelsfall kannst du den Paketnamen des Funktionsmoduls
indem Sie die generierte AndroidManifest.xml
prüfen. Gehen Sie nach der Erstellung des Projekts
an <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml
,
Das sollte ungefähr so aussehen:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" featureSplit="DynamicFeatureModule" package="com.example.dynamicfeatureapp" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" /> <dist:module dist:instant="false" dist:title="@string/title_dynamicfeaturemodule" > <dist:delivery> <dist:install-time /> </dist:delivery> <dist:fusing dist:include="true" /> </dist:module> <application /> </manifest>
Der featureSplit
-Wert sollte dem Namen des dynamischen Funktionsmoduls entsprechen und das Paket entspricht dem applicationId
-Wert des Basis-App-Moduls. app:graphPackage
ist die Kombination aus diesen Elementen: com.example.dynamicfeatureapp.DynamicFeatureModule
.
Zu einem Diagramm mit der Einschließen-dynamischen Navigation navigieren
Es ist nur möglich, zum startDestination
eines
include-dynamic
-Navigationsdiagramm. Das dynamische Modul ist verantwortlich für seine
eigenen Navigationsdiagramm
und die Basis-App kennt das nicht.
Durch den dynamischen include-dynamischen Mechanismus kann das Basis-App-Modul einen
verschachteltes Navigationsdiagramm
die im dynamischen Modul definiert ist. Diese verschachtelte Navigationsgrafik
wie bei jedem verschachtelten Navigationsdiagramm. Im Stammnavigationsdiagramm (d. h. im übergeordneten
der verschachtelten Grafik) kann nur die verschachtelte Navigationsgrafik selbst als
und nicht die untergeordneten Elemente. Daher wird startDestination
verwendet, wenn
ist der Graph „include-dynamicnavigation“ das Ziel.
Beschränkungen
- In Dynamisch enthaltenen Grafiken werden derzeit keine Deeplinks unterstützt.
- Dynamisch geladene verschachtelte Grafiken (d. h. ein
<navigation>
-Element mit einemapp:moduleName
) unterstützen derzeit keine Deeplinks.