Hedefler arasında veri geçirme

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:

  1. Gezinme Düzenleyici'de bağımsız değişkeni alan hedefi tıklayın.
  2. Özellikler panelinde, Ekle (+) seçeneğini tıklayın.
  3. 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.
  4. 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.
  5. 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.
  6. 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çin app: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.

Projenize Güvenli Arg'lar 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 uygulamalısınız.

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 işlemi uyarınca gradle.properties dosyanızda android.useAndroidX=true bulunması gerekir.

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ıfa SpecifyAmountFragmentDirections 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. İşleminiz defaultValue 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ıfa ConfirmationFragmentArgs adı verilir. Bağımsız değişkenleri almak için bu sınıfın fromBundle() 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:

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.

Sana Özel

Codelab uygulamaları

Videolar