Mithilfe der Navigation können Sie Daten an einen Navigationsvorgang anhängen, indem Sie Argumente definieren nach einem Ziel suchen. Ein Nutzerprofilziel kann z. B. eine User-ID Argument, um zu bestimmen, welcher Nutzer angezeigt werden soll.
Im Allgemeinen sollten Sie es vorziehen, nur eine minimale Datenmenge zu übergeben.
zwischen den Zielen. Sie sollten beispielsweise einen Schlüssel übergeben, um ein Objekt abzurufen.
anstatt das Objekt selbst zu übergeben, da es den Gesamtspeicherplatz für alle gespeicherten Zustände
ist auf Android-Geräten eingeschränkt. Wenn Sie große Datenmengen übergeben müssen,
ein ViewModel
wie beschrieben in
ViewModel – Übersicht
Zielargumente definieren
Um Daten zwischen Zielen zu übergeben, definieren Sie zunächst das -Argument, indem Sie es zum an das sie gesendet wird, gehen Sie so vor:
- Führen Sie im Navigationseditor folgende Schritte aus: Klicken Sie auf das Ziel, das das Argument empfängt.
- Klicken Sie im Bereich Attribute auf Hinzufügen (+).
- Geben Sie im Fenster Argument-Link hinzufügen den Namen des Arguments ein. Argumenttyp, ob für das Argument Nullwerte zulässig sind, sowie ein Standardwert, falls erforderlich.
- Klicken Sie auf Hinzufügen. Beachten Sie, dass das Argument jetzt in den Argumenten erscheint. im Bereich Attribute.
- Klicken Sie dann auf die entsprechende Aktion, die Sie zu diesem Ziel führt. Das neu hinzugefügte Argument im Bereich Attribute sollte jetzt angezeigt werden. im Abschnitt Standardwerte der Argumente.
Sie können auch sehen, dass das Argument in XML hinzugefügt wurde. Klicken Sie auf den Tab Text. um zur XML-Ansicht zu wechseln. Beachten Sie, dass Ihr Argument dem Ziel, das das Argument empfängt. Hier ein Beispiel:
<fragment android:id="@+id/myFragment" > <argument android:name="myArg" app:argType="integer" android:defaultValue="0" /> </fragment>
Unterstützte Argumenttypen
Die Navigationsbibliothek unterstützt die folgenden Argumenttypen:
Typ | app:argType-Syntax | Unterstützung für Standardwerte | Von Routen verarbeitet | Nullwerte zulässig |
---|---|---|---|---|
Ganzzahl | app:argType="integer" | Ja | Ja | Nein |
Frei schwebend | app:argType="float" | Ja | Ja | Nein |
Lang | app:argType="long" | Ja, Standardwerte müssen immer mit einem "L" enden. Suffix (z.B. „123L“). | Ja | Nein |
Boolesch | app:argType="boolean" | Ja – „wahr“ oder „false“ | Ja | Nein |
String | app:argType="string" | Ja | Ja | Ja |
Ressourcenreferenz | app:argType="reference" | Ja, Standardwerte müssen das Format "@resourceType/resourceName" haben. (z.B. „@style/myCustomStyle“) oder „0“ | Ja | Nein |
Anpassbar | app:argType="<type>", wobei <type> ist der voll qualifizierte Klassenname von Parcelable . |
Unterstützt den Standardwert „@null“. Unterstützt keine anderen Standardwerte. | Nein | Ja |
Benutzerdefinierte Serialisierbarkeit | app:argType="<type>", wobei <type> ist der voll qualifizierte Klassenname von Serializable . |
Unterstützt den Standardwert „@null“. Unterstützt keine anderen Standardwerte. | Nein | Ja |
Benutzerdefinierter Enum-Wert | app:argType="<type>", wobei <type> ist der voll qualifizierte Name der Aufzählung. | Ja. Standardwerte müssen mit dem unqualifizierten Namen übereinstimmen (z. B. "SUCCESS", um MyEnum.SUCCESS zu entsprechen). | Nein | Nein |
Wenn ein Argumenttyp Nullwerte unterstützt, können Sie folgenden Standardwert deklarieren:
Null mithilfe von android:defaultValue="@null"
.
Routen, Deeplinks und URIs mit ihren Argumenten können aus Strings geparst werden. Dies ist bei Verwendung benutzerdefinierter Datentypen wie Parcelables und Serialisierbaren wie in der vorherigen Tabelle dargestellt. Speichern Sie die Daten an einem anderen Ort, z. B. in einer ViewModel-Ressource, um benutzerdefinierte komplexe Daten zu übergeben. oder eine Datenbank speichern und während der Navigation nur eine Kennung übergeben. und rufen Sie nach Abschluss der Navigation die Daten am neuen Speicherort ab.
Wenn Sie einen der benutzerdefinierten Typen auswählen, wird das Dialogfeld Kurs auswählen angezeigt. werden Sie aufgefordert, die entsprechende Klasse für diesen Typ auszuwählen. Tab Projekt können Sie einen Kurs aus Ihrem aktuellen Projekt auswählen.
Sie können <abgeleiteter Typ> auswählen, damit die Navigationsbibliothek bestimmt den Typ basierend auf dem bereitgestellten Wert.
Sie können Array aktivieren, um anzugeben, dass das Argument ein Array des ausgewählten Wert für Typ Beachten Sie Folgendes:
- Arrays von Enums und Arrays von Ressourcenverweisen werden nicht unterstützt.
- Arrays unterstützen Werte, für die Nullwerte zulässig sind, unabhängig von der Unterstützung für solche Werte.
-Wert des zugrunde liegenden Typs. Wenn Sie beispielsweise
Mit
app:argType="integer[]"
können Sieapp:nullable="true"
für Folgendes verwenden: angeben, dass die Übergabe eines Null-Arrays akzeptabel ist. - Arrays unterstützen einen einzelnen Standardwert: „@null“. In Arrays werden keine unterstützt anderer Standardwert.
Zielargument in einer Aktion überschreiben
Argumente und Standardwerte auf Zielebene werden von allen Aktionen verwendet, zum Ziel navigieren können. Bei Bedarf können Sie den Standardwert eines -Arguments (oder legen Sie ein fest, falls es noch nicht vorhanden ist), indem Sie ein Argument im Aktionsebene. Dieses Argument muss denselben Namen und Typ haben wie das Argument im Ziel deklariert sein.
Der folgende XML-Code deklariert eine Aktion mit einem -Argument, das die Methode Argument auf Zielebene aus dem vorherigen Beispiel:
<action android:id="@+id/startMyFragment"
app:destination="@+id/myFragment">
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="1" />
</action>
Sichere Args verwenden, um Daten mit Typsicherheit zu übergeben
Die Navigationskomponente verfügt über ein Gradle-Plug-in namens Safe Args, das einfache Objekt- und Builder-Klassen für typsichere Navigation und Zugriff auf beliebige zugehöriger Argumente. Sichere Args wird dringend für die Navigation und Daten übergeben werden, da die Typsicherheit gewährleistet ist.
Wenn Sie Gradle nicht verwenden, können Sie die Einstellung Args-Plug-in. In diesen Fällen können Sie Bundles verwenden, um Daten übergeben.
如需将 Safe Args 添加到您的项目,请在顶层 build.gradle
文件中包含以下 classpath
:
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") } }
您还必须应用以下两个可用插件之一。
如需生成适用于 Java 模块或 Java 和 Kotlin 混合模块的 Java 语言代码,请将以下行添加到应用或模块的 build.gradle
文件中:
Groovy
plugins { id 'androidx.navigation.safeargs' }
Kotlin
plugins { id("androidx.navigation.safeargs") }
此外,如需生成仅适用于 Kotlin 模块的 Kotlin 语言代码,请添加以下行:
Groovy
plugins { id 'androidx.navigation.safeargs.kotlin' }
Kotlin
plugins { id("androidx.navigation.safeargs.kotlin") }
根据迁移到 AndroidX 文档,您的 gradle.properties
文件中必须具有 android.useAndroidX=true
。
Nachdem Sie sichere Argumente aktiviert haben, enthält der generierte Code Folgendes: für jede Aktion sowie für jedes Senden und Empfangsziel.
Für jedes Ziel, von dem eine Aktion ausgeht, wird eine Klasse erstellt. Name dieser Klasse ist der Name des ursprünglichen Ziels, angehängt mit dem Wort „Directions“. Wenn das Ausgangsziel z. B. ein Fragment ist namens
SpecifyAmountFragment
hat die generierte Klasse den NamenSpecifyAmountFragmentDirections
.Diese Klasse verfügt über eine -Methode für jede Aktion, die in der ursprünglichen Ziel.
Für jede Aktion, die zur Übergabe des Arguments verwendet wird, wird eine innere Klasse erstellt, deren auf der Aktion basiert. Wenn die Aktion beispielsweise
confirmationAction,
: Die Klasse heißtConfirmationAction
. Wenn Ihr Aktion Argumente ohnedefaultValue
enthält, verwenden Sie die Methode zugehörige Aktionsklasse, um den Wert der Argumente festzulegen.Für das Empfängerziel wird eine Klasse erstellt. Der Name dieser Klasse ist Der Name des Ziels, an den das Wort „Args“ angehängt ist. Wenn beispielsweise Das Zielfragment hat den Namen
ConfirmationFragment,
(das generierte Klasse heißtConfirmationFragmentArgs
.fromBundle()
dieses Kurses verwenden zum Abrufen der Argumente.
Das folgende Beispiel zeigt, wie Sie mit diesen Methoden ein Argument und
übergeben Sie ihn an den navigate()
.
:
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); }
Verwenden Sie im Code für das Empfängerziel die Methode getArguments()
.
um das Bundle abzurufen und seinen Inhalt zu verwenden. Wenn Sie die -ktx
-Abhängigkeiten verwenden,
Kotlin-Nutzer können für den Zugriff auch den Property-Delegaten by navArgs()
verwenden.
Argumente.
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 + ""); }
Sichere Argumente mit einer globalen Aktion verwenden
Wenn Sie sichere Args mit einem
globale Maßnahmen,
müssen Sie einen android:id
-Wert für Ihr <navigation>
-Stammelement angeben,
Beispiel:
<?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>
Bei der Navigation wird eine Directions
-Klasse für das <navigation>
-Element generiert, das
basierend auf dem Wert android:id
. Beispiel: <navigation>
-Element mit android:id=@+id/main_nav
enthält, wird die generierte Klasse aufgerufen.
MainNavDirections
Alle Ziele innerhalb des <navigation>
-Elements haben
Methoden für den Zugriff auf alle verknüpften globalen Aktionen
wie im vorherigen Abschnitt beschrieben.
Daten zwischen Zielen mit Bundle-Objekten übergeben
Auch wenn Sie Gradle nicht verwenden, können Sie Argumente zwischen Zielen übergeben, indem Sie
mit Bundle
-Objekten. Bundle
-Objekt erstellen und an das Ziel übergeben
mit navigate()
wie im folgenden Beispiel:
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);
Verwenden Sie im Code des Empfängerziels die Methode getArguments()
, um
Bundle
abrufen und deren Inhalt verwenden:
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"));
Daten an das Startziel übergeben
Sie können Daten an das Startziel Ihrer App übergeben. Zunächst müssen Sie explizit
ein Bundle
erstellen, das die Daten enthält Verwenden Sie als Nächstes eine der folgenden Optionen:
versucht, die Bundle
an das Startziel zu übergeben:
- Wenn Sie Ihre
NavHost
programmatisch erstellen, rufen SieNavHostFragment.create(R.navigation.graph, args)
, wobeiargs
dieBundle
, die Ihre Daten enthält. - Andernfalls können Sie Startzielargumente festlegen, indem Sie eines der
folgende Überlastung von
NavController.setGraph()
: <ph type="x-smartling-placeholder">- </ph>
- Verwenden Sie die ID des Diagramms:
navController.setGraph(R.navigation.graph, args)
- Verwenden Sie die Grafik selbst:
navController.setGraph(navGraph, args)
- Verwenden Sie die ID des Diagramms:
Rufen Sie zum Abrufen der Daten am Startziel Folgendes auf:
Fragment.getArguments()
Überlegungen zu ProGuard
Wenn Sie Ihren Code verkleinern, müssen Sie Folgendes verhindern: Parcelable
,
Serializable
- und Enum
-Klassennamen werden nicht im Rahmen der
Minifizierungsprozess zu durchlaufen. Dazu haben Sie zwei Möglichkeiten:
- @Notizen-Annotationen verwenden
- Verwenden Sie Keepnames-Regeln.
In den folgenden Unterabschnitten werden diese Ansätze erläutert.
@Notizen-Annotationen verwenden
Im folgenden Beispiel werden @Keep
-Annotationen zu Modellklassendefinitionen hinzugefügt:
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-Regeln verwenden
Sie können der Datei proguard-rules.pro
auch keepnames
-Regeln hinzufügen, wie hier gezeigt:
im folgenden Beispiel:
proguard-rules.pro
...
-keepnames class com.path.to.your.ParcelableArg
-keepnames class com.path.to.your.SerializableArg
-keepnames class com.path.to.your.EnumArg
...
Weitere Informationen
Weitere Informationen zur Navigation finden Sie hier: zusätzliche Ressourcen.