Navigasyon, bir hedef için bağımsız değişkenler tanımlayarak verileri bir gezinme işlemine eklemenize olanak tanır. Örneğin, bir kullanıcı profili hedefi, hangi kullanıcının gösterileceğini belirlemek için bir kullanıcı kimliği bağımsız değişkeni alabilir.
Genel olarak, hedefler arasında yalnızca minimum miktarda veri iletmeyi tercih etmeniz önerilir. Örneğin, Android'de tüm kayıtlı durumların toplam alanı sınırlı olduğundan, bir nesneyi almak için nesnenin kendisini iletmek yerine bir anahtar iletmeniz gerekir. Büyük miktarda veri iletmeniz gerekiyorsa ViewModel'e genel bakış bölümünde açıklandığı gibi bir ViewModel
kullanın.
Hedef bağımsız değişkenlerini tanımlama
Hedefler arasında veri aktarmak için önce bağımsız değişkeni, aşağıdaki adımları uygulayarak alan adı alan hedefe ekleyerek tanımlayın:
- Gezinme Düzenleyici'de bağımsız değişkeni alan hedefi tıklayın.
- Özellikler panelinde Ekle'yi (+) tıklayın.
- Görünen Bağımsız Değişken Bağlantısı Ekle penceresine bağımsız değişken adını, bağımsız değişken türünü, bağımsız değişkenin boş olup olmadığını ve gerekirse varsayılan değeri girin.
- Ekle'yi tıklayın. Parametrenin artık Özellikler panelindeki Parametreler listesinde göründüğünü fark edin.
- Ardından, sizi bu hedefe götüren ilgili işlemi tıklayın. Özellikler panelinde, yeni eklenen bağımsız değişkeninizi Bağımsız Değişken Varsayılan Değerleri bölümünde görebilirsiniz.
Ayrıca bağımsız değişkenin XML'e eklendiğini de görebilirsiniz. XML görünümüne geçmek için Metin sekmesini tıklayın ve bağımsız değişkeninizin, bağımsız değişkeni alan hedefe eklendiğini fark edin. Aşağıda bir örnek gösterilmektedir:
<fragment android:id="@+id/myFragment" > <argument android:name="myArg" app:argType="integer" android:defaultValue="0" /> </fragment>
Desteklenen bağımsız değişken türleri
Gezinme kitaplığı aşağıdaki bağımsız değişken türlerini destekler:
Tür | app:argType söz dizimi | Varsayılan değerler için destek | Rotalar tarafından yönetilir | Boş değer atanabilir |
---|---|---|---|---|
Tam sayı | app:argType="integer" | Evet | Evet | Hayır |
Havada Süzülen | app:argType="float" | Evet | Evet | Hayır |
Uzun | app:argType="long" | Evet: Varsayılan değerler her zaman "L" son ekiyle bitmelidir (ör. "123L"). | Evet | Hayır |
Boole | app:argType="boolean" | Evet: "true" veya "false" | Evet | Hayır |
Dize | app:argType="string" | Evet | Evet | Evet |
Kaynak Referansı | app:argType="reference" | Evet: Varsayılan değerler "@resourceType/resourceName" (ör. "@style/myCustomStyle") veya "0" biçiminde olmalıdır. | Evet | Hayır |
Özel Paketlenebilir | app:argType="<type>". Burada <type>, Parcelable sınıfının tam nitelikli sınıf adıdır. |
"@null" varsayılan değerini destekler. Diğer varsayılan değerleri desteklemez. | Hayır | Evet |
Özel Serileştirilebilir | app:argType="<type>". Burada <type>, Serializable sınıfının tam nitelikli sınıf adıdır. |
"@null" varsayılan değerini destekler. Diğer varsayılan değerleri desteklemez. | Hayır | Evet |
Özel Enum | app:argType="<type>". Burada <type>, enum'un tam nitelikli adıdır. | Evet: Varsayılan değerler, tam olmayan adla eşleşmelidir (ör. MyEnum.SUCCESS ile eşleşmek için "SUCCESS"). | Hayır | Hayır |
Bir bağımsız değişken türü boş değerleri destekliyorsa android:defaultValue="@null"
kullanarak varsayılan olarak boş bir değer belirtebilirsiniz.
Rotalar, derin bağlantılar ve URI'ler, bağımsız değişkenleriyle birlikte dizelerden ayrıştırılabilir. Bu, önceki tabloda gösterildiği gibi Parcelables ve Serializables gibi özel veri türleri kullanılarak yapılamaz. Özel karmaşık verileri iletmek için verileri ViewModel veya veritabanı gibi başka bir yerde depolayın ve gezinirken yalnızca bir tanımlayıcı iletin. Ardından, gezinme tamamlandıktan sonra verileri yeni konumda alın.
Özel türlerden birini seçtiğinizde Sınıf Seç iletişim kutusu görünür ve bu tür için ilgili sınıfı seçmeniz istenir. Proje sekmesi, mevcut projenizden bir sınıf seçmenize olanak tanır.
Gezinme kitaplığının türü sağlanan değere göre belirlemesi için <inferred type> seçeneğini belirleyebilirsiniz.
Bağımsız değişkenin, seçilen Tür değerinin bir dizisi olması gerektiğini belirtmek için Dizi'yi işaretleyebilirsiniz. Aşağıdakileri göz önünde bulundurun:
- Liste dizileri ve kaynak referansı dizileri desteklenmez.
- Diziler, temel türün boş değer desteğinden bağımsız olarak boş değerleri destekler. Örneğin,
app:argType="integer[]"
kullanıldığında, null bir dizi iletmenin kabul edilebilir olduğunu belirtmek içinapp:nullable="true"
kullanabilirsiniz. - Diziler yalnızca tek bir varsayılan değeri destekler: "@null". Diziler başka bir varsayılan değeri desteklemez.
Bir işlemdeki hedef bağımsız değişkenini geçersiz kılma
Hedef düzeyindeki bağımsız değişkenler ve varsayılan değerler, hedefe giden tüm işlemler tarafından kullanılır. Gerekirse işlem düzeyinde bir bağımsız değişken tanımlayarak bağımsız değişkenin varsayılan değerini geçersiz kılabilirsiniz (veya henüz mevcut değilse bir değer ayarlayabilirsiniz). Bu bağımsız değişken, hedefte tanımlanan bağımsız değişkenle aynı ada ve türe sahip olmalıdır.
Aşağıdaki XML, önceki örnekteki hedef düzeyindeki bağımsız değişkeni geçersiz kılan bir bağımsız değişken içeren bir işlem tanımlar:
<action android:id="@+id/startMyFragment"
app:destination="@+id/myFragment">
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="1" />
</action>
Verileri tür güvenliğiyle iletmek için Safe Args'i kullanma
Navigasyon bileşeninde, tür açısından güvenli gezinme ve ilişkili tüm bağımsız değişkenlere erişim için basit nesne ve oluşturucu sınıfları oluşturan Safe Args adlı bir Gradle eklentisi bulunur. Tür güvenliği sağladığı için Safe Args, gezinme ve veri aktarımı için önemle tavsiye edilir.
Gradle kullanmıyorsanız SafeArgs eklentisini kullanamazsınız. Bu gibi durumlarda, verileri doğrudan iletmek için paketleri kullanabilirsiniz.
Projenize Safe Args eklemek için üst düzey build.gradle
dosyanıza aşağıdaki classpath
öğesini ekleyin:
Groovy
buildscript { repositories { google() } dependencies { def nav_version = "2.8.4" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } }
Kotlin
buildscript { repositories { google() } dependencies { val nav_version = "2.8.4" classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version") } }
Ayrıca, mevcut iki eklentiden birini de uygulamanız gerekir.
Java veya karma Java ve Kotlin modüllerine uygun Java dil kodu oluşturmak için bu satırı uygulamanızın veya modülünüzün build.gradle
dosyasına ekleyin:
Groovy
plugins { id 'androidx.navigation.safeargs' }
Kotlin
plugins { id("androidx.navigation.safeargs") }
Alternatif olarak, yalnızca Kotlin modüllerine uygun Kotlin kodu oluşturmak için şunları ekleyin:
Groovy
plugins { id 'androidx.navigation.safeargs.kotlin' }
Kotlin
plugins { id("androidx.navigation.safeargs.kotlin") }
AndroidX'e Taşıma bölümünde belirtildiği gibi, gradle.properties
dosyanızda android.useAndroidX=true
olmalıdır.
Güvenli bağımsız değişkenleri etkinleştirdikten sonra oluşturulan kodunuz, her işlem için ve her gönderen ve alıcı hedef için aşağıdaki türde güvenli sınıflar ve yöntemler içerir.
Bir işlemin başladığı her hedef için bir sınıf oluşturulur. Bu sınıfın adı, başlangıç noktasının adına "Yol tarifleri" kelimesinin eklenmesidir. Örneğin, kaynak hedef
SpecifyAmountFragment
adlı bir parça ise oluşturulan sınıfSpecifyAmountFragmentDirections
olarak adlandırılır.Bu sınıf, kaynak hedefte tanımlanan her işlem için bir yönteme sahiptir.
Argümanını iletmek için kullanılan her işlem için adı işleme dayalı bir iç sınıf oluşturulur. Örneğin, işlem
confirmationAction,
olarak adlandırılırsa sınıfConfirmationAction
olarak adlandırılır. İşleminizdefaultValue
içermeyen bağımsız değişkenler içeriyorsa bağımsız değişkenlerin değerini ayarlamak için ilişkili işlem sınıfını kullanırsınız.Alıcı hedef için bir sınıf oluşturulur. Bu sınıfın adı, hedefin adına "Args" kelimesinin eklenmesidir. Örneğin, hedef parça
ConfirmationFragment,
olarak adlandırılırsa oluşturulan sınıfConfirmationFragmentArgs
olarak adlandırılır. Parametreleri almak için bu sınıfınfromBundle()
yöntemini kullanın.
Aşağıdaki örnekte, bir bağımsız değişken ayarlamak ve bunu navigate()
yöntemine iletmek için bu yöntemlerin nasıl kullanılacağı gösterilmektedir:
Kotlin
override fun onClick(v: View) { val amountTv: EditText = view!!.findViewById(R.id.editTextAmount) val amount = amountTv.text.toString().toInt() val action = SpecifyAmountFragmentDirections.confirmationAction(amount) v.findNavController().navigate(action) }
Java
@Override public void onClick(View view) { EditText amountTv = (EditText) getView().findViewById(R.id.editTextAmount); int amount = Integer.parseInt(amountTv.getText().toString()); ConfirmationAction action = SpecifyAmountFragmentDirections.confirmationAction(); action.setAmount(amount); Navigation.findNavController(view).navigate(action); }
Alıcı hedefin kodunda, paketi almak ve içeriğini kullanmak için getArguments()
yöntemini kullanın. -ktx
bağımlılıkları kullanılırken Kotlin kullanıcıları, bağımsız değişkenlere erişmek için by navArgs()
mülk temsilcisini de kullanabilir.
Kotlin
val args: ConfirmationFragmentArgs by navArgs() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { val tv: TextView = view.findViewById(R.id.textViewAmount) val amount = args.amount tv.text = amount.toString() }
Java
@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { TextView tv = view.findViewById(R.id.textViewAmount); int amount = ConfirmationFragmentArgs.fromBundle(getArguments()).getAmount(); tv.setText(amount + ""); }
Safe Args'i genel işlemle kullanma
Güvenli bağımsız değişkenleri global bir işlemle kullanırken aşağıdaki örnekte gösterildiği gibi kök <navigation>
öğeniz için bir android:id
değeri sağlamanız gerekir:
<?xml version="1.0" encoding="utf-8"?> <navigation xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/main_nav" app:startDestination="@id/mainFragment"> ... </navigation>
Gezinme, <navigation>
öğesi için android:id
değerine dayalı bir Directions
sınıfı oluşturur. Örneğin, android:id=@+id/main_nav
içeren bir <navigation>
öğeniz varsa oluşturulan sınıf MainNavDirections
olarak adlandırılır. <navigation>
öğesindeki tüm hedefler, önceki bölümde açıklanan yöntemlerle ilişkili tüm genel işlemlere erişmek için oluşturulmuş yöntemlere sahiptir.
Paket nesneleriyle hedefler arasında veri geçirme
Gradle kullanmıyorsanız Bundle
nesnelerini kullanarak hedefler arasında yine bağımsız değişken iletebilirsiniz. Aşağıdaki örnekte gösterildiği gibi bir Bundle
nesnesi oluşturun ve navigate()
kullanarak hedefe iletin:
Kotlin
val bundle = bundleOf("amount" to amount) view.findNavController().navigate(R.id.confirmationAction, bundle)
Java
Bundle bundle = new Bundle(); bundle.putString("amount", amount); Navigation.findNavController(view).navigate(R.id.confirmationAction, bundle);
Alıcı hedefinizin kodunda, Bundle
öğesini almak ve içeriğini kullanmak için getArguments()
yöntemini kullanın:
Kotlin
val tv = view.findViewById<TextView>(R.id.textViewAmount) tv.text = arguments?.getString("amount")
Java
TextView tv = view.findViewById(R.id.textViewAmount); tv.setText(getArguments().getString("amount"));
Başlangıç hedefine veri aktarma
Uygulamanızın başlangıç hedefine veri iletebilirsiniz. Öncelikle, verileri içeren bir Bundle
açıkça oluşturmanız gerekir. Ardından, Bundle
değerini başlangıç hedefine iletmek için aşağıdaki yaklaşımlardan birini kullanın:
NavHost
öğenizi programatik olarak oluşturuyorsanızNavHostFragment.create(R.navigation.graph, args)
işlevini çağırın. Buradaargs
, verilerinizi barındıranBundle
öğesidir.- Aksi takdirde,
NavController.setGraph()
işlevinin aşağıdaki aşırı yüklemelerinden birini çağırarak başlangıç hedefi bağımsız değişkenlerini ayarlayabilirsiniz:- Grafiğin kimliğini kullanın:
navController.setGraph(R.navigation.graph, args)
- Grafiğin kendisini kullanın:
navController.setGraph(navGraph, args)
- Grafiğin kimliğini kullanın:
Başlangıç hedefinizdeki verileri almak için Fragment.getArguments()
işlevini çağırın.
ProGuard ile ilgili dikkat edilmesi gereken noktalar
Kodu küçültüyorsanız Parcelable
, Serializable
ve Enum
sınıf adlarınızın, sadeleştirme işlemi kapsamında karartılmasını önlemeniz gerekir. Bunu iki şekilde yapabilirsiniz:
- @Keep ek açıklamalarını kullanın.
- Adları koruma kurallarını kullanın.
Aşağıdaki alt bölümlerde bu yaklaşımlar özetlenmiştir.
@Keep ek açıklamalarını kullanma
Aşağıdaki örnekte, model sınıfı tanımlarına @Keep
ek açıklamaları eklenmiştir:
Kotlin
@Keep class ParcelableArg : Parcelable { ... } @Keep class SerializableArg : Serializable { ... } @Keep enum class EnumArg { ... }
Java
@Keep public class ParcelableArg implements Parcelable { ... } @Keep public class SerializableArg implements Serializable { ... } @Keep public enum EnumArg { ... }
Adları koruma kurallarını kullanma
Aşağıdaki örnekte gösterildiği gibi, proguard-rules.pro
dosyanıza keepnames
kuralları da ekleyebilirsiniz:
proguard-rules.pro
...
-keepnames class com.path.to.your.ParcelableArg
-keepnames class com.path.to.your.SerializableArg
-keepnames class com.path.to.your.EnumArg
...
Ek kaynaklar
Gezinme hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara göz atın.