Gezinme, bir hedef için bağımsız değişkenler tanımlayarak gezinme işlemine veri eklemenize olanak tanır. Örneğin, bir kullanıcı profili hedefi, hangi kullanıcının gösterileceğini belirlemek için kullanıcı kimliği bağımsız değişkenini alabilir.
Genel olarak, hedefler arasında yalnızca minimum miktarda veri aktarımını kesinlikle tercih etmelisiniz. Örneğin, Android'de kaydedilen tüm durumlar için toplam alan sınırlı olduğundan, nesnenin kendisini iletmek yerine bir nesneyi almak için anahtar iletmeniz gerekir. Büyük miktarlarda veri iletmeniz gerekiyorsa ViewModel'e genel bakış bölümünde açıklandığı gibi bir ViewModel
kullanın.
Hedef bağımsız değişkenleri tanımlayın
Hedefler arasında veri aktarmak için önce aşağıdaki adımları uygulayarak bağımsız değişkeni, alıcısı olan hedefe ekleyerek tanımlayın:
- Gezinme Düzenleyici'de bağımsız değişkeni alan hedefi tıklayın.
- Özellikler panelinde, Ekle (+) seçeneğini tıklayın.
- Görüntülenen Bağımsız değişken Bağlantısı Ekle penceresinde, bağımsız değişken adını, bağımsız değişken türünü, bağımsız değişkenin boş değerli olup olmadığını ve gerekirse varsayılan bir değer girin.
- Ekle'yi tıklayın. Bağımsız değişkenin artık Özellikler panelindeki Bağımsız Değişkenler listesinde göründüğüne dikkat edin.
- Ardından, sizi bu hedefe götüren ilgili işlemi tıklayın. Özellikler panelinde, artık yeni eklediğiniz bağımsız değişkeni Bağımsız değişken Varsayılan Değerleri bölümünde görebilirsiniz.
Bağımsız değişkenin XML olarak 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 unutmayın. Aşağıda bir örnek gösterilmiştir:
<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 | İşlenen rotalar | 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 bir "L" son eki ile bitmelidir (ör. "123L"). | Evet | Hayır |
Boole | app:argType="boole" | Evet: "doğru" veya "yanlış" | 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 Parçalanabilir | app:argType="<type>"; burada <type>, Parcelable öğesinin 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 öğesinin 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 Sıralama | 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şmesi için "BAŞARILI"). | Hayır | Hayır |
Bir bağımsız değişken türü null değerleri destekliyorsa android:defaultValue="@null"
kullanarak varsayılan null değerini bildirebilirsiniz.
Rotalar, derin bağlantılar ve bağımsız değişkenleriyle URI'lar dizelerden ayrıştırılabilir. Önceki tabloda görüldüğü gibi, Parselables ve Serializables gibi özel veri türleri kullanıldığında bu mümkün değildir. Özel karmaşık verileri aktarmak için verileri ViewModel veya veritabanı gibi başka bir yerde depolayın ve yalnızca gezinirken bir tanımlayıcı iletin. Ardından, gezinme sonlandırıldıktan sonra verileri yeni konumda alın.
Özel türlerden birini seçtiğinizde, Sınıf Seçin iletişim kutusu görünür ve söz konusu tür için karşılık gelen sınıfı seçmenizi ister. Proje sekmesi, mevcut projenizden bir sınıf seçmenizi sağlar.
Gezinme kitaplığının, türü sağlanan değere göre belirlemesi için <inffer type> (tahmin edilen tür) 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 onay kutusunu işaretleyebilirsiniz. Aşağıdakileri göz önünde bulundurun:
- Sıralama dizisi ve kaynak başvurusu dizileri desteklenmez.
- Diziler, temel türdeki null özellikli değerlerin desteklenmesinden bağımsız olarak null değerleri destekler. Örneğin,
app:argType="integer[]"
kullanmak, null bir dizi geçirmenin kabul edilebilir olduğunu belirtmek içinapp:nullable="true"
kullanmanıza olanak tanır. - Diziler "@null" şeklindeki tek bir varsayılan değeri destekler. Diziler başka hiçbir varsayılan değeri desteklemez.
Bir işlemde hedef bağımsız değişkeni 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 bir bağımsız değişkenin varsayılan değerini geçersiz kılabilirsiniz (veya hâlihazırda yoksa bir bağımsız değişken ayarlayabilirsiniz). Bu bağımsız değişken, hedefte belirtilen bağımsız değişkenle aynı ada ve türde olmalıdır.
Aşağıdaki XML, önceki örnekte bulunan hedef düzeyindeki bağımsız değişkeni geçersiz kılan bir bağımsız değişken içeren bir işlemi bildirmektedir:
<action android:id="@+id/startMyFragment"
app:destination="@+id/myFragment">
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="1" />
</action>
Tür güvenliği ile veri aktarmak için Güvenli Anahtarlar kullanma
Gezinme bileşeninde, tür güvenli gezinme ve ilişkili 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. Güvenli Aramalar, tür güvenliği sağladığından verilerde gezinmek ve veri aktarmak 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.
Güvenli Aramalar'ı projenize eklemek için üst düzey build.gradle
dosyanıza aşağıdaki classpath
öğesini ekleyin:
Modern
buildscript { repositories { google() } dependencies { def nav_version = "2.7.7" classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version" } }
Kotlin
buildscript { repositories { google() } dependencies { val nav_version = "2.7.7" classpath("androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version") } }
Ayrıca, mevcut iki eklentiden birini uygulamanız gerekir.
Java'ya veya karma Java ve Kotlin modüllerine uygun Java dili kodu oluşturmak için şu satırı uygulamanızın veya modülünüzün build.gradle
dosyasına ekleyin:
Modern
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 şunu ekleyin:
Modern
plugins { id 'androidx.navigation.safeargs.kotlin' }
Kotlin
plugins { id("androidx.navigation.safeargs.kotlin") }
AndroidX'e Taşıma uyarınca gradle.properties
dosyanızda android.useAndroidX=true
bulunmalıdır.
Güvenli Aramalar'ı etkinleştirdikten sonra, oluşturduğunuz kod, her bir işlem için ve her gönderme ve alma hedefi için aşağıdaki tür güvenli sınıfları ve yöntemleri içerir.
İşlemin kaynaklandığı her hedef için bir sınıf oluşturulur. Bu sınıfın adı, kaynak hedefin adı ve sonuna "Directions" kelimesi eklenir. Örneğin, kaynak hedef
SpecifyAmountFragment
adlı bir parçaysa oluşturulan sınıfaSpecifyAmountFragmentDirections
adı verilir.Bu sınıfta, kaynak hedefte tanımlanan her işlem için bir yöntem bulunur.
Bağımsız değişkeni geçirmek amacıyla kullanılan her işlem için, adı işleme dayalı olan bir iç sınıf oluşturulur. Örneğin, işlem
confirmationAction,
olarak adlandırılırsa sınıfın adıConfirmationAction
olur. İş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ı hedefi için bir sınıf oluşturulur. Bu sınıfın adı, sonuna "Args" kelimesi eklenen hedefin adıdır. Örneğin, hedef parçanın adı
ConfirmationFragment,
ise oluşturulan sınıfaConfirmationFragmentArgs
adı verilir. Bağımsız değişkenleri 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 geçirmek 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); }
Alma hedefinin kodunda, paketi almak ve içeriğini kullanmak için getArguments()
yöntemini kullanın. -ktx
bağımlılıklarını kullanırken, Kotlin kullanıcıları bağımsız değişkenlere erişmek için by navArgs()
özellik yetkisini 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 + ""); }
Güvenli Arg'ları küresel işlem ile kullanın
Güvenli Anahtarları genel bir işlemle kullanırken, kök <navigation>
öğeniz için aşağıdaki örnekte gösterildiği gibi 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ğerini temel alan 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>
öğesi içindeki tüm hedefler, önceki bölümde açıklanan yöntemleri kullanarak ilişkili tüm genel işlemlere erişmek için yöntemler oluşturmuştur.
Paket nesneleriyle hedefler arasında veri geçirme
Gradle kullanmıyorsanız Bundle
nesnelerini kullanarak hedefler arasında bağımsız değişkenler aktarabilirsiniz. Bir Bundle
nesnesi oluşturun ve bu nesneyi, aşağıdaki örnekte olduğu gibi 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"));
Verileri başlangıç hedefine iletme
Verileri uygulamanızın başlangıç hedefine aktarabilirsiniz. Öncelikle, verileri barındıran bir Bundle
açıkça oluşturmanız gerekir. Ardından, Bundle
öğesini başlangıç hedefine geçirmek için aşağıdaki yaklaşımlardan birini kullanın:
NavHost
öğenizi programatik olarak oluşturuyorsanızNavHostFragment.create(R.navigation.graph, args)
yöntemini çağırın. Buradaargs
, verilerinizi barındıranBundle
değeridir.- Aksi takdirde, aşağıdaki
NavController.setGraph()
aşırı yüklemelerinden birini çağırarak başlangıç hedefi bağımsız değişkenlerini ayarlayabilirsiniz:- Grafik kimliğini kullanın:
navController.setGraph(R.navigation.graph, args)
- Grafiğin kendisini kullanın:
navController.setGraph(navGraph, args)
- Grafik kimliğini kullanın:
Başlangıç hedefinizdeki verileri almak için Fragment.getArguments()
numaralı telefonu arayın.
ProGuard ile ilgili dikkat edilmesi gereken noktalar
Kodunuzu daraltıyorsanız küçültme işlemi kapsamında Parcelable
, Serializable
ve Enum
sınıf adlarınızda kod karartmanın önüne geçmeniz gerekir. Bunu iki yöntemden birini kullanarak yapabilirsiniz:
- @Keep ek açıklamalarını kullanın.
- Keepnames kurallarını kullanın.
Aşağıdaki alt bölümlerde bu yaklaşımlar özetlenmektedir.
@Keep ek açıklamalarını kullanma
Aşağıdaki örnekte, model sınıfı tanımlarına @Keep
ek açıklamaları eklenir:
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 { ... }
Keepnames 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 bakın.