Gezinme bileşeni, Kotlin'in tür güvenliğine sahip oluşturucularına dayanan Kotlin tabanlı bir alana özgü dil veya DSL sağlar. Bu API, grafiğinizi bildirerek oluşturmak yerine Kotlin kodunuzda oluşturmanıza olanak tanır
daha kolay olur. Bu, uygulamanızın özel bir kitle oluşturmak
gezinmeyi kolaylaştırır. Örneğin, uygulamanız bir
harici bir web hizmetinden gezinme yapılandırmasını
dinamik olarak bir gezinme grafiği oluşturmak için
onCreate()
işlevi.
Bağımlılıklar
Kotlin DSL'yi Parçalarla birlikte kullanmak için aşağıdaki bağımlılığı uygulamanızın
build.gradle
dosyası:
Groovy
dependencies { def nav_version = "2.9.2" api "androidx.navigation:navigation-fragment-ktx:$nav_version" }
Kotlin
dependencies { val nav_version = "2.9.2" api("androidx.navigation:navigation-fragment-ktx:$nav_version") }
Grafik oluşturma
Burada, Google Ads kurallarından yola çıkarak hazırlanan Sunflower
uygulamasında bulabilirsiniz. Bunun için
Örneğin, iki hedefimiz var: home
ve plant_detail
. home
Hedefi, kullanıcı uygulamayı ilk kez başlattığında mevcuttur. Bu hedef, kullanıcının bahçesindeki bitkilerin listesini gösterir. Kullanıcı bitkilerden birini seçtiğinde uygulama plant_detail
hedefine gider.
Şekil 1'de bu hedefler,
Uygulamanın kullandığı plant_detail
hedef ve bir işlem (to_plant_detail
)
home
- plant_detail
arası rotayı izleyin.

home
ve plant_detail
ile birlikte şu işlemi gerçekleştiren bir işlem:
birbirine bağlar.Kotlin DSL gezinme grafiği barındırma
Uygulamanızın gezinme grafiğini oluşturabilmek için öncelikle
grafiğe dönüştürülebilir. Bu örnekte parçalar kullanıldığı için, grafiği
NavHostFragment
bir
FragmentContainerView
:
<!-- activity_garden.xml -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.fragment.app.FragmentContainerView
android:id="@+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true" />
</FrameLayout>
Bu örnekte app:navGraph
özelliğinin ayarlanmadığına dikkat edin. Grafik
bir kaynak olarak tanımlanmadığından
res/navigation
klasörü olduğundan onCreate()
öğesinin bir parçası olarak ayarlanması gerekir
bu etkinliği takip etmeniz gerekir.
XML'de, bir işlem hedef kimliğini bir veya daha fazla bağımsız değişkenle birbirine bağlar. Ancak, Navigasyon DSL'sini kullanırken bir rota, yol gösterir. Bu, DSL kullanılırken işlem kavramının olmadığı anlamına gelir.
Bir sonraki adım, işletme hedefinizi tanımlarken kullanacağınız rotaları grafiğe dönüştürülebilir.
Grafiğiniz için rotalar oluşturma
XML tabanlı gezinme grafikleri, bir üründen diğerine
adımına geçelim. Her id
için sayısal bir sabit sayı oluşturulur
özelliğinin değeri. Derleme zamanında oluşturulan bu statik kimlikler
Böylece, Gezinme DSL'sini kullanmak için çalışma zamanında gezinme grafiğinizi oluştururken kullanabilirsiniz.
seri girilebilir veri türünü kullanır.
türler yerine
Kimlikler. Her rota, benzersiz bir türle temsil edilir.
Bağımsız değişkenlerle çalışırken, bunlar rotaya eklenir tür'ü seçin. Bu sayede, gezinme bağımsız değişkenleriniz için tür güvenliğine sahip olabilirsiniz.
@Serializable data object Home
@Serializable data class Plant(val id: String)
NavGraphBuilder DSL ile grafik oluşturma
Güzergahlarınızı tanımladıktan sonra, gezinme grafiğini oluşturabilirsiniz.
val navController = findNavController(R.id.nav_host_fragment)
navController.graph = navController.createGraph(
startDestination = Home
) {
fragment<HomeFragment, Home> {
label = resources.getString(R.string.home_title)
}
fragment<PlantDetailFragment, PlantDetail> {
label = resources.getString(R.string.plant_detail_title)
}
}
Bu örnekte, iki parçalı hedef
fragment()
DSL oluşturucu işlevi. Bu işlev, iki tür gerektirir
bağımsız değişkenler
,
Önce bir Fragment
sınıfı
API'yi kullanabilirsiniz. Bunu ayarlamak
tanımlanmış parça hedeflerde android:name
özelliğini ayarlayarak
anlamına gelir.
İkinci olarak rota. Bu, Any
tarihinden itibaren seri hale getirilebilir bir tür olmalıdır. Google
bu hedef tarafından kullanılacak gezinme bağımsız değişkenlerini içermelidir.
ve türlerini seçin.
İşlev, hedef etiketi gibi ek yapılandırma için isteğe bağlı bir lambda'yı ve özel bağımsız değişkenler ile derin bağlantılar için yerleşik oluşturucu işlevlerini de kabul eder.
Kotlin DSL grafiğinizle gezinme
Son olarak, NavController.navigate()
çağrılarını kullanarak home
'ten plant_detail
'a gidebilirsiniz:
private fun navigateToPlant(plantId: String) {
findNavController().navigate(route = PlantDetail(id = plantId))
}
PlantDetailFragment
işlevinde,
geçerli
NavBackStackEntry
ve sesli arama yapıyorum
toRoute
çift tıklayın.
val plantDetailRoute = findNavController().getBackStackEntry<PlantDetail>().toRoute<PlantDetail>()
val plantId = plantDetailRoute.id
PlantDetailFragment
, ViewModel
kullanıyorsa rota örneğini şunu kullanarak alın:
SavedStateHandle.toRoute
.
val plantDetailRoute = savedStateHandle.toRoute<PlantDetail>()
val plantId = plantDetailRoute.id
Bu kılavuzun geri kalanında, yaygın olarak kullanılan gezinme grafiği öğeleri, hedefler, bunları nasıl kullanacağınızı öğreneceksiniz.
Hedefler
Kotlin DSL, üç hedef türü için yerleşik destek sağlar:
Her biri kendine ait olan Fragment
, Activity
ve NavGraph
hedefleri
oluşturmak ve yapılandırmak için kullanılabilen satır içi uzantı işlevi
seçeceğiz.
Parça hedefleri
İlgili içeriği oluşturmak için kullanılan
fragment()
DSL işlevi, kullanıcı arayüzünün parça sınıfı ve
bu hedefi benzersiz şekilde tanımlamak için kullanılan rota türü ve ardından bir lambda
Burada açıklandığı gibi ek yapılandırma sağlayabileceğiniz yöntem
Kotlin DSL grafiğiniz bölümünde görünür.
fragment<MyFragment, MyRoute> {
label = getString(R.string.fragment_title)
// custom argument types, deepLinks
}
Etkinlik hedefi
activity()
DSL işlevi, rota için bir tür parametresi alır ancak herhangi bir uygulayıcı etkinlik sınıfı için parametrelendirilmez. Bunun yerine, anahtar kelimeler için isteğe bağlı bir activityClass
bir lambda var. Bu esneklik, açık bir etkinlik sınıfının anlamlı olmadığı durumlarda örtülü intent kullanılarak başlatılması gereken bir etkinlik için etkinlik hedefi tanımlamanıza olanak tanır. Parça hedeflerde olduğu gibi,
Etiket, özel bağımsız değişkenler ve derin bağlantılar yapılandırabilirsiniz.
activity<MyRoute> {
label = getString(R.string.activity_title)
// custom argument types, deepLinks...
activityClass = MyActivity::class
}
Navigasyon grafiğinin hedefi
navigation()
DSL işlevi, iç içe yerleştirilmiş bir gezinme grafiği oluşturmak için kullanılabilir. Bu işlev bir tür alır
parametresini kullanabilirsiniz. Ayrıca iki bağımsız değişken alır: grafiğin başlangıç hedefinin rotası ve grafiği daha da yapılandırmak için bir lambda. Geçerli öğeler arasında diğer hedefler, özel bağımsız değişken yer alır
derin bağlantılar ve bu sayfa için açıklayıcı bir etiket
hedef.
Bu etiket, NavigationUI
kullanılarak gezinme grafiğinin kullanıcı arayüzü bileşenlerine bağlanması için yararlı olabilir.
@Serializable data object HomeGraph
@Serializable data object Home
navigation<HomeGraph>(startDestination = Home) {
// label, other destinations, deep links
}
Özel hedefleri destekleme
Kotlin DSL'yi doğrudan desteklemeyen bir yeni hedef türü kullanıyorsanız bu hedefleri addDestination()
kullanarak Kotlin DSL'nize ekleyebilirsiniz:
// The NavigatorProvider is retrieved from the NavController
val customDestination = navigatorProvider[CustomNavigator::class].createDestination().apply {
route = Graph.CustomDestination.route
}
addDestination(customDestination)
Alternatif olarak, yeni oluşturulan bir hedefi doğrudan grafiğe eklemek için tek adımlı artı operatörünü de kullanabilirsiniz:
// The NavigatorProvider is retrieved from the NavController
+navigatorProvider[CustomNavigator::class].createDestination().apply {
route = Graph.CustomDestination.route
}
Hedef bağımsız değişkenleri sağlama
Hedef bağımsız değişkenleri, rota sınıfının bir parçası olarak tanımlanabilir. Bunlar, herhangi bir Kotlin sınıfı için belirtilen şekilde tanımlanabilir. Gerekli bağımsız değişkenler boş değerli olmayan türler olarak tanımlanır ve isteğe bağlı bağımsız değişkenler varsayılan olarak tanımlanır değerler.
Rotaları ve bunların bağımsız değişkenlerini temsil eden temel mekanizma dize tabanlı. Rotaları modellemek için dize kullanmak, gezinme durumunun depolanmasını ve
yapılandırma sırasında diskten geri yüklendi
sistem tarafından başlatılan ve işlem
ölüm ile ilişkilendirilebilir. İşte bu nedenle
Her gezinme bağımsız değişkeni serileştirilebilir olmalıdır; yani,
bağımsız değişken değerinin bellek içi gösterimini
String
Kotlin serileştirmesi
eklenti
Google Analytics 4'teki temel alan
anahtar kelimeler
@Serializable
ek açıklaması bir nesneye eklendi.
@Serializable
data class MyRoute(
val id: String,
val myList: List<Int>,
val optionalArg: String? = null
)
fragment<MyFragment, MyRoute>
Özel türler sağlama
Özel bağımsız değişken türleri için özel bir NavType
sınıfı sağlamanız gerekir. Bu, türünüzün bir rotadan veya derin bağlantıdan tam olarak nasıl ayrıştırılacağını kontrol etmenizi sağlar.
Örneğin, bir arama ekranını tanımlamak için kullanılan bir rota, arama parametrelerini temsil eden bir sınıf içerebilir:
@Serializable
data class SearchRoute(val parameters: SearchParameters)
@Serializable
@Parcelize
data class SearchParameters(
val searchQuery: String,
val filters: List<String>
)
Özel bir NavType
şu şekilde yazılabilir:
val SearchParametersType = object : NavType<SearchParameters>(
isNullableAllowed = false
) {
override fun put(bundle: Bundle, key: String, value: SearchParameters) {
bundle.putParcelable(key, value)
}
override fun get(bundle: Bundle, key: String): SearchParameters {
return bundle.getParcelable(key) as SearchParameters
}
override fun serializeAsValue(value: SearchParameters): String {
// Serialized values must always be Uri encoded
return Uri.encode(Json.encodeToString(value))
}
override fun parseValue(value: String): SearchParameters {
// Navigation takes care of decoding the string
// before passing it to parseValue()
return Json.decodeFromString<SearchParameters>(value)
}
}
Bu, daha sonra Kotlin DSL'nizde diğer türler gibi kullanılabilir:
fragment<SearchFragment, SearchRoute>(
typeMap = mapOf(typeOf<SearchParameters>() to SearchParametersType)
) {
label = getString(R.string.plant_search_title)
}
Hedefe giderken rotanızın bir örneğini oluşturun:
val params = SearchParameters("rose", listOf("available"))
navController.navigate(route = SearchRoute(params))
Parametre, hedefteki rotadan edinilebilir:
val searchRoute = navController().getBackStackEntry<SearchRoute>().toRoute<SearchRoute>()
val params = searchRoute.parameters
Derin bağlantılar
Derin bağlantılar, XML destekli bir gezinme grafiğinde olduğu gibi herhangi bir hedefe eklenebilir. Derin bağlantı oluşturma bölümünde belirtilen prosedürlerin tümü sürece uygulanır. bir derin bağlantı oluşturmayı öğreneceksiniz.
Dolaylı derin bağlantı oluştururken
ancak o zaman hangisi için analiz edilebilecek bir XML gezinme kaynağınız yoksa
<deepLink>
öğeleri. Bu nedenle, <nav-graph>
öğesi; AndroidManifest.xml
dosyanıza intent
filtreler ekleyebilirsiniz. Amaç
sağladığınız filtrenin temel yolu, işlemi ve mime türüyle
uygulamanızın derin bağlantılarını kullanın.
Derin bağlantılar, hedefin lambda işlevi içinde deepLink
işlevi çağrılarak hedefe eklenir. Rota, parametrelenmiş bir tür olarak kabul edilir ve derin bağlantı için kullanılan URL'nin temel yolu için bir parametre basePath
kabul eder.
Ayrıca,
deepLinkBuilder
lambda var.
Aşağıdaki örnek, Home
hedefi için bir derin bağlantı URI'si oluşturmaktadır.
@Serializable data object Home
fragment<HomeFragment, Home>{
deepLink<Home>(basePath = "www.example.com/home"){
// Optionally, specify the action and/or mime type that this destination
// supports
action = "android.intent.action.MY_ACTION"
mimeType = "image/*"
}
}
URI biçimi
Derin bağlantı URI biçimi, aşağıdaki kurallar kullanılarak rotanın alanlarından otomatik olarak oluşturulur:
- Gerekli parametreler yol parametreleri olarak eklenmiştir (örnek:
/{id}
) - Varsayılan değeri olan parametreler (isteğe bağlı parametreler) sorgu parametresi olarak eklenir (örnek:
?name={name}
) - Koleksiyonlar sorgu parametresi olarak eklenir (örnek:
?items={value1}&items={value2}
) - Parametrelerin sırası, rotadaki alanların sıralamasıyla eşleşir
Örneğin, aşağıdaki rota türü:
@Serializable data class PlantDetail(
val id: String,
val name: String,
val colors: List<String>,
val latinName: String? = null,
)
Oluşturulan URI biçimi şu şekildedir:
basePath/{id}/{name}/?colors={color1}&colors={color2}&latinName={latinName}
Ekleyebileceğiniz derin bağlantı sayısıyla ilgili bir sınır yoktur. deepLink()
işlevini her çağırdığınızda, söz konusu hedef için tutulan bir listeye yeni bir derin bağlantı eklenir.
Sınırlamalar
Safe Args eklentisi, Directions
ve Arguments
sınıfları oluşturmak için XML kaynak dosyalarını aradığından Kotlin DSL ile uyumlu değildir.