Dynamic Navigator kitaplığı, Jetpack Gezinme bileşeninin işlevlerini özellik modüllerinde tanımlanan hedeflerle çalışacak şekilde genişletir. Bu kitaplık, bu hedeflere gidildiğinde isteğe bağlı özellik modüllerinin sorunsuz bir şekilde yüklenmesini de sağlar.
Kurulum
Özellik modüllerini desteklemek için uygulama modülünüzün build.gradle
dosyasında aşağıdaki bağımlılıkları kullanın:
Modern
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") }
Diğer Gezinme bağımlılıklarının özellik modüllerinizde kullanılabilmesi için api yapılandırmalarının kullanılması gerektiğini unutmayın.
Temel kullanım
Özellik modüllerini desteklemek için öncelikle uygulamanızdaki tüm NavHostFragment
örneklerini androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment
olarak değiştirin:
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host_fragment"
android:name="androidx.navigation.dynamicfeatures.fragment.DynamicNavHostFragment"
app:navGraph="@navigation/nav_graph"
... />
Ardından, com.android.dynamic-feature
modülünüzün gezinme grafiklerinde DynamicNavHostFragment
ile ilişkilendirilmiş tüm <activity>
, <fragment>
veya <navigation>
hedeflerine app:moduleName
özelliği ekleyin.
Bu özellik, Dynamic Navigator kitaplığına hedefin belirttiğiniz ada sahip bir özellik modülüne ait olduğunu bildirir.
<fragment
app:moduleName="myDynamicFeature"
android:id="@+id/featureFragment"
android:name="com.google.android.samples.feature.FeatureFragment"
... />
Bu hedeflerden birine gittiğinizde, Dynamic Navigator kitaplığı öncelikle özellik modülünün yüklü olup olmadığını kontrol eder. Özellik modülü zaten mevcutsa uygulamanız beklendiği gibi hedefe gider. Modül mevcut değilse uygulamanız, modülü yüklerken bir ara ilerleme parçası hedefi gösterir. İlerleme parçasının varsayılan uygulaması, ilerleme çubuğu olan temel bir kullanıcı arayüzü gösterir ve yükleme hatalarını yönetir.
![bir özellik modülüne ilk kez gittiğinizde kullanıcı arayüzünde ilerleme çubuğu gösteren iki yükleme ekranı](https://developer.android.com/static/images/guide/navigation/dfm-nav-loading.png?authuser=5&hl=tr)
Bu kullanıcı arayüzünü özelleştirmek veya yükleme ilerleme durumunu kendi uygulama ekranınızdan manuel olarak yönetmek için bu konudaki İlerleme parçasını özelleştirme ve İstek durumunu izleme bölümlerine göz atın.
app:moduleName
belirtilmeyen hedefler değişiklik olmadan çalışmaya devam eder ve uygulamanız normal bir NavHostFragment
kullanıyormuş gibi davranır.
İlerleme parçasını özelleştirme
app:progressDestination
özelliğini, yükleme ilerlemesini yönetmek için kullanmak istediğiniz hedefin kimliğine ayarlayarak her bir gezinme grafiğinin ilerleme parçası uygulamasını geçersiz kılabilirsiniz. Özel ilerleme hedefiniz, AbstractProgressFragment
kaynağından gelen bir Fragment
olmalıdır.
Yükleme ilerlemesi, hatalar ve diğer etkinliklerle ilgili bildirimler için soyut yöntemleri geçersiz kılmanız gerekir. Daha sonra, yüklemenin ilerleme durumunu
istediğiniz bir kullanıcı arayüzünde gösterebilirsiniz.
Varsayılan uygulamanın DefaultProgressFragment
sınıfı, yüklemenin ilerleme durumunu göstermek için bu API'yi kullanır.
İstek durumunu izleme
Dynamic Navigator kitaplığı, isteğe bağlı sunum için kullanıcı deneyimi en iyi uygulamalarına benzer bir kullanıcı deneyimi akışı uygulamanıza olanak tanır. Bu akışta kullanıcı, kurulumun tamamlanmasını beklerken önceki bir ekranın bağlamında kalır. Bu, ara bir kullanıcı arayüzü veya ilerleme parçası göstermenize gerek olmadığı anlamına gelir.
![bir özellik modülünün indirilmekte olduğunu belirten bir simgenin bulunduğu alt gezinme çubuğunun gösterildiği ekran](https://developer.android.com/static/images/guide/navigation/nav-dfm-ui.png?authuser=5&hl=tr)
Bu senaryoda tüm yükleme durumlarını, ilerleme durumu değişikliklerini, hataları vb. izlemek ve yönetmek sizin sorumluluğunuzdadır.
Engellemeyen bu gezinme akışını başlatmak için aşağıdaki örnekte gösterildiği gibi DynamicInstallMonitor
içeren bir DynamicExtras
nesnesini NavController.navigate()
öğesine iletin:
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); )
navigate()
çağırdıktan hemen sonra, gezinme denemesinin bir özellik modülü yüklemesiyle sonuçlanıp sonuçlanmadığını görmek için installMonitor.isInstallRequired
değerini kontrol etmeniz gerekir.
- Değer
false
ise normal bir hedefe gidersiniz ve başka bir şey yapmanız gerekmez. Değer
true
ise şu andainstallMonitor.status
içinde olanLiveData
nesnesini gözlemlemeye başlamanız gerekir. BuLiveData
nesnesi, Play Core kitaplığındanSplitInstallSessionState
güncellemeleri yayar. Bu güncellemeler, kullanıcı arayüzünü güncellemek için kullanabileceğiniz yükleme ilerleme durumu etkinliklerini içerir. Gerekirse kullanıcı onayı isteme de dahil olmak üzere tüm ilgili durumları Play Core kılavuzunda özetlendiği şekilde ele almayı unutmayın.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); } } }); }
Yükleme tamamlandığında LiveData
nesnesi SplitInstallSessionStatus.INSTALLED
durumunu gösterir. Ardından NavController.navigate()
tekrar aramalısınız. Modül yüklendiğinden çağrı başarılı olur ve uygulama beklendiği gibi hedefe gider.
Yükleme tamamlandığında veya yükleme başarısız olduğunda (örneğin, yükleme tamamlandığında veya yükleme başarısız olduğunda) bir terminal durumuna ulaştıktan sonra, bellek sızıntılarını önlemek için LiveData
gözlemcinizi kaldırmanız gerekir. Durumun bir terminal durumunu temsil edip etmediğini kontrol etmek için SplitInstallSessionStatus.hasTerminalStatus()
kullanabilirsiniz.
Bu gözlemcinin örnek uygulamasını görmek için AbstractProgressFragment
adresine bakın.
Dahil edilen grafikler
Dynamic Navigator kitaplığı, özellik modüllerinde tanımlanan grafikleri dahil etmeyi destekler. Bir özellik modülünde tanımlanmış bir grafiği eklemek için şunları yapın:
Aşağıdaki örnekte gösterildiği gibi
<include/>
yerine<include-dynamic/>
kullanın:<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" />
<include-dynamic ... />
içinde şu özellikleri belirtmeniz gerekir:app:graphResName
: Gezinme grafiği kaynak dosyasının adı. Ad, grafiğin dosya adından türetilir. Örneğin, grafikres/navigation/nav_graph.xml
içindeyse kaynak adınav_graph
olur.android:id
- grafik hedef kimliği. Dynamic Navigator kitaplığı, dahil edilen grafiğin kök öğesinde bulunan tümandroid:id
değerlerini yoksayar.app:moduleName
: modülün paket adı.
Doğru grafikPaketini kullanma
Gezinme bileşeni, belirtilen navGraph
öğesini özellik modülünden ekleyemeyeceğinden app:graphPackage
öğesinin doğru olması önemlidir.
Bir dinamik özellik modülünün paket adı, modülün adı temel uygulama modülünün applicationId
bölümüne eklenerek oluşturulur. Dolayısıyla, temel uygulama modülünün applicationId
değeri com.example.dynamicfeatureapp
ise ve dinamik özellik modülünün adı DynamicFeatureModule
ise dinamik modülün paket adı com.example.dynamicfeatureapp.DynamicFeatureModule
olur. Bu paket adı büyük/küçük harfe duyarlıdır.
Herhangi bir şüpheniz varsa oluşturulan AndroidManifest.xml
öğesini kontrol ederek özellik modülünün paket adını doğrulayabilirsiniz. Projeyi oluşturduktan sonra <DynamicFeatureModule>/build/intermediates/merged_manifest/debug/AndroidManifest.xml
adresine gidin. URL aşağıdaki gibi görünmelidir:
<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>
featureSplit
değeri dinamik özellik modülünün adıyla, paket ise temel uygulama modülünün applicationId
değeriyle eşleşmelidir. app:graphPackage
, şunların kombinasyonudur: com.example.dynamicfeatureapp.DynamicFeatureModule
.
Dinamik gezinme grafiğine gitme
Bir include-dynamic
gezinme grafiğinin startDestination
bölümüne yalnızca gidilebilir. Dinamik modül kendi gezinme grafiğinden sorumludur ve temel uygulama bundan haberdar değildir.
include-dinamik mekanizması, temel uygulama modülünün dinamik modülde tanımlanan iç içe yerleştirilmiş bir gezinme grafiği içermesini sağlar. İç içe yerleştirilmiş bu gezinme grafiği, iç içe yerleştirilmiş gezinme grafikleri gibi davranır. Kök gezinme grafiği (yani iç içe yerleştirilmiş grafiğin üst öğesi), iç içe yerleştirilmiş gezinme grafiğinin kendisini yalnızca hedef olarak tanımlayabilir, bu grafiğin alt öğelerini tanımlayamaz. Dolayısıyla, dahil etme-dinamik gezinme grafiği hedef olduğunda startDestination
kullanılır.
Sınırlamalar
- Dinamik olarak eklenmiş grafikler şu anda derin bağlantıları desteklememektedir.
- Dinamik olarak yüklenmiş iç içe yerleştirilmiş grafikler (yani,
app:moduleName
içeren bir<navigation>
öğesi) şu anda derin bağlantıları desteklememektedir.