Biblioteka Dynamic Navigator rozszerza funkcjonalność Komponent Nawigacji Jetpack do obsługi miejsc docelowych. zdefiniowane w moduły funkcji. Ta biblioteka umożliwia też bezproblemową instalację funkcji na żądanie. modułów podczas przechodzenia do tych miejsc docelowych.
Konfiguracja
Aby obsługiwać moduły funkcji, użyj tych zależności w pliku build.gradle
modułu aplikacji:
Odlotowe
dependencies { def nav_version = "2.7.7" 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.7.7" 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") }
Pamiętaj, że inne zależności nawigacji powinny używać konfiguracji API. aby były one dostępne dla modułów funkcji.
Podstawowe wykorzystanie
Aby obsługiwać moduły funkcji, najpierw zmień wszystkie wystąpienia
NavHostFragment
w aplikacji, aby
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"
... />
Następnie dodaj atrybut app:moduleName
do dowolnych <activity>
, <fragment>
lub
<navigation>
miejsca docelowe w module com.android.dynamic-feature
wykresy nawigacyjne powiązane z DynamicNavHostFragment
.
Ten atrybut informuje bibliotekę Dynamic Navigator, że miejsce docelowe
należy do modułu funkcji o podanej przez Ciebie nazwie.
<fragment
app:moduleName="myDynamicFeature"
android:id="@+id/featureFragment"
android:name="com.google.android.samples.feature.FeatureFragment"
... />
Po przejściu do jednego z tych miejsc biblioteka Dynamic Navigator najpierw sprawdza, czy jest zainstalowany moduł funkcji. Jeśli funkcja już jest dostępny, aplikacja przejdzie do miejsca docelowego zgodnie z oczekiwaniami. Jeśli moduł nie jest dostępny, aplikacja wyświetla pośredni fragment postępu podczas instalowania modułu. Domyślna implementacja Fragment postępu pokazuje podstawowy interfejs użytkownika z paskiem postępu i obsługuje błędów instalacji.
![2 ekrany wczytywania, które pokazują interfejs z paskiem postępu podczas nawigacji.
do modułu funkcji.](https://developer.android.com/static/images/guide/navigation/dfm-nav-loading.png?authuser=9&hl=pl)
Aby dostosować ten interfejs użytkownika lub ręcznie obsługiwać instalację postępów na ekranie swojej aplikacji, zobacz Dostosuj fragment postępu i Sekcje Monitorowanie stanu żądania w tym temacie.
Miejsca docelowe bez wartości app:moduleName
będą nadal działać bez
zmienia się i zachowuje tak, jakby aplikacja używała zwykłego NavHostFragment
.
Dostosuj fragment postępu
Możesz zastąpić implementację fragmentu postępu w przypadku każdego wykresu nawigacyjnego
przez ustawienie atrybutu app:progressDestination
na identyfikator miejsca docelowego
który ma być używany do obsługi postępu instalacji. Twój postęp niestandardowy
miejsce docelowe powinno być
Fragment
, które pochodzi z
AbstractProgressFragment
Musisz zastąpić abstrakcyjne metody w przypadku powiadomień o instalacji
postęp, błędy i inne zdarzenia. Następnie możesz wyświetlić postęp instalacji w
interfejsu użytkownika.
Implementacja domyślna
DefaultProgressFragment
klasa używa tego interfejsu API do pokazywania postępu instalacji.
Monitorowanie stanu żądania
Biblioteka Dynamic Navigator umożliwia wdrożenie procesu UX podobnego do jedno w Sprawdzone metody UX w zakresie dostarczania na żądanie, gdy użytkownik pozostaje w kontekście poprzedniego ekranu, czekając na aby zakończyć instalację. Oznacza to, że nie musisz wyświetlać poziomu średniozaawansowanego interfejsu użytkownika ani fragmentu postępu.
![ekran z dolnym paskiem nawigacyjnym z ikoną
który jest pobierany](https://developer.android.com/static/images/guide/navigation/nav-dfm-ui.png?authuser=9&hl=pl)
W tym scenariuszu odpowiadasz za monitorowania i obsługi wszystkich stanów instalacji, zmian postępu, błędów oraz i tak dalej.
Aby rozpocząć ten nieblokujący proces nawigacji, przekaż
DynamicExtras
obiekt zawierający
DynamicInstallMonitor
do
NavController.navigate()
,
jak w tym przykładzie:
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); )
Bezpośrednio po wywołaniu funkcji navigate()
sprawdź wartość
installMonitor.isInstallRequired
, aby sprawdzić, czy próba nawigacji spowodowała
w ramach instalacji modułów funkcji.
- Jeśli wartość to
false
, przechodzisz do normalnego miejsca docelowego i nie nie muszą robić nic więcej. Jeśli wartość to
true
, należy zacząć obserwować obiektLiveData
, który jest teraz w domenieinstallMonitor.status
. Ten obiektLiveData
emitujeSplitInstallSessionState
. i aktualizacje z biblioteki Play Core. Te aktualizacje obejmują instalację zdarzeń postępu, których możesz używać do aktualizowania interfejsu użytkownika. Pamiętaj o załatwianiu wszystkich spraw odpowiednie stany opisane w Przewodnik po Google Play Core w tym prośba o potwierdzenie użytkownika w razie potrzeby.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); } } }); }
Po zakończeniu instalacji obiekt LiveData
wysyła komunikat
Stan SplitInstallSessionStatus.INSTALLED
. Następnie należy zadzwonić
NavController.navigate()
. Moduł jest już zainstalowany, więc wywołanie
teraz się powiedzie, a aplikacja przejdzie do miejsca docelowego zgodnie z oczekiwaniami.
Po osiągnięciu stanu terminala, np. po zakończeniu instalacji lub po
instalacja się nie powiedzie, usuń obserwatora LiveData
, aby uniknąć pamięci
wyciek danych. Aby sprawdzić, czy stan wskazuje stan terminala, użyj funkcji
SplitInstallSessionStatus.hasTerminalStatus()
Zobacz AbstractProgressFragment
aby zobaczyć przykład zastosowania funkcji tego obserwatora.
Uwzględnione wykresy
Biblioteka Dynamic Navigator obsługuje wstawianie wykresów zdefiniowanych w modułów funkcji. Aby dołączyć wykres zdefiniowany w funkcji wykonaj te czynności:
Użyj
<include-dynamic/>
zamiast<include/>
, jak pokazano poniżej przykład:<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" />
W usłudze
<include-dynamic ... />
musisz określić te atrybuty:app:graphResName
: nazwa pliku zasobów grafu nawigacyjnego. pochodzi z nazwy pliku wykresu. Jeśli na przykład wykres jest wres/navigation/nav_graph.xml
, nazwa zasobu tonav_graph
.android:id
– identyfikator miejsca docelowego wykresu. Biblioteka Dynamic Navigator ignoruje wszystkie wartościandroid:id
, które znajdują się w elemencie głównym argumentu uwzględniony wykres.app:moduleName
: nazwa pakietu modułu.
Użyj właściwego pakietu wykresów
Ważne jest, aby app:graphPackage
była poprawna jako nawigacja
komponent nie może dołączyć określonego elementu navGraph
z funkcji
W przeciwnym razie.
Nazwa pakietu modułu funkcji dynamicznych jest tworzona przez dołączenie parametru
nazwa modułu na applicationId
podstawowego modułu aplikacji. Jeśli więc
podstawowy moduł aplikacji ma applicationId
o wartości com.example.dynamicfeatureapp
oraz
moduł funkcji dynamicznych nazywa się DynamicFeatureModule
, a pakiet
nazwa modułu dynamicznego będzie
com.example.dynamicfeatureapp.DynamicFeatureModule
Nazwa pakietu to
.
W razie wątpliwości możesz potwierdzić nazwę pakietu modułu funkcji.
sprawdzając wygenerowane dane AndroidManifest.xml
. Po utworzeniu projektu przejdź do:
do: <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml
,
Powinien on wyglądać mniej więcej tak:
<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>
Wartość featureSplit
powinna być zgodna z nazwą modułu funkcji dynamicznych, a pakiet pasuje do applicationId
podstawowego modułu aplikacji. app:graphPackage
to kombinacja tych elementów: com.example.dynamicfeatureapp.DynamicFeatureModule
.
Przechodzenie do wykresu uwzględniania dynamicznej nawigacji
Można przejść tylko do startDestination
Wykres nawigacyjny include-dynamic
. Moduł dynamiczny odpowiada za
a aplikacja podstawowa o tym nie wie.
Mechanizm include-dynamiczny pozwala w podstawowym module aplikacji zawierać element
zagnieżdżony wykres nawigacyjny
zdefiniowanej w module dynamicznym. Ten zagnieżdżony wykres nawigacyjny zachowuje się
jak każdy zagnieżdżony wykres nawigacyjny. Główny wykres nawigacyjny (czyli nadrzędny
zagnieżdżonego wykresu) może zostać zdefiniowany jedynie jako zagnieżdżony wykres nawigacyjny
miejsca docelowego, a nie jego elementów podrzędnych. Dlatego startDestination
jest używany, gdy
a wykres uwzględnia-dynamiczną nawigację jest miejscem docelowym.
Ograniczenia
- Wykresy dołączane dynamicznie nie obsługują obecnie precyzyjnych linków.
- Dynamicznie ładowane wykresy zagnieżdżone (element
<navigation>
z parametremapp:moduleName
) nie obsługują obecnie precyzyjnych linków.