הניווט מאפשר לצרף נתונים לפעולת ניווט על ידי הגדרת ארגומנטים ליעד. לדוגמה, יעד של פרופיל משתמש עשוי לקבל מזהה משתמש ארגומנט כדי לקבוע איזה משתמש להציג.
באופן כללי, מומלץ מאוד להעביר רק את הכמות המינימלית של נתונים
בין היעדים. לדוגמה, צריך להעביר מפתח כדי לאחזר אובייקט
במקום להעביר את האובייקט עצמו, בתור השטח הכולל לכל המצבים השמורים
מוגבלת ב-Android. אם אתם צריכים להעביר כמויות גדולות של נתונים, אפשר להשתמש
ViewModel
כמו שמתואר
צפייה בסקירה הכללית של המודל.
הגדרת ארגומנטים של יעד
כדי להעביר נתונים בין יעדים, קודם צריך להגדיר את הארגומנט על ידי הוספתו היעד שמקבל אותו באמצעות השלבים הבאים:
- בעורך הניווט, לוחצים על היעד שמקבל את הארגומנט.
- בחלונית מאפיינים, לוחצים על הוספה (+).
- בחלון הוספת קישור לארגומנט שמופיע, מזינים את שם הארגומנט, סוג ארגומנט, האם הארגומנט הוא null וערך ברירת מחדל, אם הדרושים.
- לוחצים על הוספה. שימו לב שהארגומנט מופיע עכשיו בקטע ארגומנטים רשימה בחלונית מאפיינים.
- לאחר מכן, לוחצים על הפעולה המתאימה שמובילה ליעד הזה. עכשיו תוכלו לראות את הארגומנט החדש שהוספתם בחלונית מאפיינים. בקטע ערכי ברירת מחדל של ארגומנטים.
אפשר גם לראות שהארגומנט נוסף ב-XML. לוחצים על הכרטיסייה טקסט. כדי לעבור לתצוגת XML ולראות שהארגומנט נוסף היעד שמקבל את הארגומנט. כך אפשר לראות דוגמה:
<fragment android:id="@+id/myFragment" > <argument android:name="myArg" app:argType="integer" android:defaultValue="0" /> </fragment>
סוגי הארגומנטים הנתמכים
ספריית הניווט תומכת בסוגי הארגומנטים הבאים:
סוג | תחביר app:argType | תמיכה בערכי ברירת מחדל | טיפול במסלולים | אפס |
---|---|---|---|---|
מספר שלם | app:argType="integer" | כן | כן | לא |
בלונים | app:argType="float" | כן | כן | לא |
ארוך | app:argType="long" | כן – ערכי ברירת המחדל חייבים תמיד להסתיים ב-L. סיומת (למשל, 123L). | כן | לא |
ערך בוליאני | app:argType="boolean" | כן – 'true' או 'false' | כן | לא |
מחרוזת | app:argType="string" | כן | כן | כן |
הפניה למשאבים | app:argType="reference" | כן - ערכי ברירת המחדל חייבים להיות בפורמט ' @resourceType/resourceName' (למשל ' @style/myCustomStyle') או '0' | כן | לא |
חבילה בהתאמה אישית | app:argType="<type>", כאשר <type> הוא שם הסיווג המוגדר במלואו של Parcelable |
אפשר להשתמש בערך ברירת המחדל ' @null'. לא תומכת בערכי ברירת מחדל אחרים. | לא | כן |
ניתן להתאמה אישית בסדרה | app:argType="<type>", כאשר <type> הוא שם הסיווג המוגדר במלואו של Serializable |
אפשר להשתמש בערך ברירת המחדל ' @null'. לא תומכת בערכי ברירת מחדל אחרים. | לא | כן |
טיפוסים בני מנייה (enum) מותאם אישית | app:argType="<type>", כאשר <type> הוא השם המוגדר במלואו של טיפוס הטיפוסים (enum) | כן - ערכי ברירת המחדל חייבים להתאים לשם הלא כשיר (למשל, "Success" כדי להתאים ל-MyEnum.You) | לא | לא |
אם סוג ארגומנט תומך בערכי null, אפשר להצהיר על ערך ברירת מחדל של
null באמצעות שימוש ב-android:defaultValue="@null"
.
אפשר לנתח ממחרוזות נתיבים, קישורי עומק ומזהי URI עם הארגומנטים שלהם. לא ניתן לעשות זאת באמצעות סוגי נתונים בהתאמה אישית כמו 'מגרשים' או ניתן להשתמש בהם בהמשכיות, כפי שמוצג בטבלה הקודמת. כדי להעביר נתונים מורכבים בהתאמה אישית, אחסנו את הנתונים במקום אחר, כגון ViewModel או מסד נתונים ולהעביר מזהה רק בזמן הניווט. ואז מאחזרים את הנתונים במיקום החדש אחרי שהניווט הסתיים.
כשבוחרים אחד מהסוגים המותאמים אישית, מופיעה תיבת הדו-שיח בחירת כיתה תוצג בקשה לבחור את הכיתה המתאימה לסוג הזה. הכרטיסייה Project מאפשרת לבחור כיתה מהפרויקט הנוכחי.
ניתן לבחור <infer type> להצגת ספריית הניווט לקבוע את הסוג על סמך הערך שצוין.
אפשר לסמן את Array כדי לציין שהארגומנט צריך להיות מערך של נבחר ערך סוג. שימו לב:
- אין תמיכה במערכים של טיפוסים בני מנייה (enum) ומערכים של הפניות משאבים.
- מערכי תמיכה תומכים בערכי null, ללא קשר לתמיכה במאפיין null
מסוג הבסיס. לדוגמה, שימוש ב-
האפליקציה
app:argType="integer[]"
מאפשרת לך להשתמש ב-app:nullable="true"
כדי לציין שהעברת מערך null מקובלת. - מערכים תומכים בערך ברירת מחדל יחיד, " @null". מערכים לא תומכים בכלל ערך ברירת מחדל אחר.
שינוי ארגומנט יעד בפעולה
בכל הפעולות שעושות שימוש בארגומנטים ברמת היעד ובערכי ברירת המחדל ניווט אל היעד. במקרה הצורך, אפשר לשנות את ערך ברירת המחדל של ארגומנט (או להגדיר ארגומנט אם הוא עדיין לא קיים) על ידי הגדרת ארגומנט ברמת הפעולה. הארגומנט הזה צריך להיות באותו שם וסוג של הארגומנט שהוצהר ביעד.
קוד ה-XML הבא מצהיר על פעולה עם ארגומנט שעוקף את הארגומנט ברמת היעד מהדוגמה הקודמת:
<action android:id="@+id/startMyFragment"
app:destination="@+id/myFragment">
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="1" />
</action>
שימוש ב-Safe Args כדי להעביר נתונים עם אבטחת סוג
רכיב הניווט כולל פלאגין של Gradle בשם Safe Args שנוצר מחלקות פשוטות של אובייקטים ו-builder בשביל ניווט בטוח לסוג גישה. ארגומנטים קשורים. מומלץ מאוד להשתמש ב-Safe Args לניווט ול העברת נתונים, כי זה מבטיח את בטיחות הסוג.
אם אתם לא משתמשים ב-Gradle, לא תוכלו להשתמש הפלאגין Args. במקרים כאלה, אפשר להשתמש בחבילות כדי ישירות להעביר נתונים.
To add Safe Args
to your project, include the following classpath
in your top level build.gradle
file:
Groovy
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") } }
You must also apply one of two available plugins.
To generate Java language code suitable for Java or mixed Java and Kotlin modules, add
this line to your app or module's build.gradle
file:
Groovy
plugins { id 'androidx.navigation.safeargs' }
Kotlin
plugins { id("androidx.navigation.safeargs") }
Alternatively, to generate Kotlin code suitable for Kotlin-only modules add:
Groovy
plugins { id 'androidx.navigation.safeargs.kotlin' }
Kotlin
plugins { id("androidx.navigation.safeargs.kotlin") }
You must have android.useAndroidX=true
in your
gradle.properties
file as per
Migrating to AndroidX.
אחרי ההפעלה של Safe Args, הקוד שנוצר מכיל את הדברים הבאים מקלידים את הסיווגים הבטוחים ואת השיטות הבטוחות לכל פעולה, כמו גם לכל שליחה היעד שמתקבל.
המערכת יוצרת כיתה לכל יעד שממנו בוצעה הפעולה. השם במחלקה הזו הוא השם של יעד המוצא שמצורף לסיומת "Directions". לדוגמה, אם יעד המוצא הוא מקטע בשם
SpecifyAmountFragment
, המחלקה שנוצרה נקראתSpecifyAmountFragmentDirections
.לקטגוריה הזו יש שיטה לכל פעולה שהוגדרה בשדה היעד.
לכל פעולה שמשמשת להעברת הארגומנט, נוצרת מחלקה פנימית מבוסס על הפעולה. למשל, אם הפעולה נקראת
confirmationAction,
הכיתה נקראתConfirmationAction
. אם הפעולה מכילה ארגומנטים בליdefaultValue
, אז צריך להשתמש בפונקציה מחלקה של הפעולה המשויכת כדי להגדיר את ערך הארגומנטים.נוצרת כיתה ליעד המקבל. השם של הכיתה הזו הוא שם היעד שמצורף אליו במילה "Args". לדוגמה, אם השם של קטע היעד הוא
ConfirmationFragment,
. הכיתה נקראתConfirmationFragmentArgs
. שימוש בfromBundle()
של הכיתה ולאחזור הארגומנטים.
הדוגמה הבאה מראה איך להשתמש בשיטות האלה כדי להגדיר ארגומנט
להעביר אותו אל navigate()
method:
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); }
בקוד של היעד המקבל, משתמשים בשיטה getArguments()
כדי לאחזר את החבילה ולהשתמש בתוכן שלה. כשמשתמשים ביחסי התלות של -ktx
,
משתמשי Kotlin יכולים גם להשתמש בבעל הגישה לנכס by navArgs()
כדי לקבל גישה
ארגומנטים.
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 עם פעולה גלובלית
כשמשתמשים בארגומנטים בטוחים עם
פעולה גלובלית,
צריך לספק ערך android:id
לרכיב השורש <navigation>
,
שמוצגת בדוגמה הבאה:
<?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>
הניווט יוצר מחלקה Directions
עבור הרכיב <navigation>
ש
על סמך הערך android:id
. לדוגמה, אם יש לך <navigation>
עם android:id=@+id/main_nav
, המחלקה שנוצרה נקראת
MainNavDirections
. לכל היעדים ברכיב <navigation>
יש
שיטות שנוצרות לגישה לכל הפעולות הגלובליות המשויכות באמצעות
כמתואר בקטע הקודם.
העברת נתונים בין יעדים באמצעות אובייקטים של חבילות
גם אם אתם לא משתמשים ב-Gradle, אפשר להעביר ארגומנטים בין יעדים באמצעות
באמצעות Bundle
אובייקטים. יצירת אובייקט Bundle
והעברה שלו ליעד
באמצעות navigate()
, כמו בדוגמה הבאה:
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);
בקוד של היעד המקבל, משתמשים בשיטה getArguments()
כדי
מאחזרים את Bundle
ומשתמשים בתוכן שלו:
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"));
העברת נתונים ליעד ההתחלה
אפשר להעביר נתונים ליעד ההתחלה של האפליקציה. קודם כל, צריך להגדיר
ליצור Bundle
שמכיל את הנתונים. בשלב הבא, משתמשים באחת מהאפשרויות הבאות
גישות להעברת Bundle
ליעד ההתחלה:
- אם יוצרים את
NavHost
באופן פרוגרמטי, צריך להתקשרNavHostFragment.create(R.navigation.graph, args)
, כאשרargs
Bundle
שמכיל את הנתונים שלך. - אחרת, אפשר להגדיר ארגומנטים של יעד להתחלה על ידי קריאה לאחד
עומסי-היתר הבאים של
NavController.setGraph()
:- צריך להשתמש במזהה התרשים:
navController.setGraph(R.navigation.graph, args)
- משתמשים בתרשים עצמו:
navController.setGraph(navGraph, args)
- צריך להשתמש במזהה התרשים:
כדי לאחזר את הנתונים ביעד ההתחלה, צריך להתקשר
Fragment.getArguments()
שיקולים ב-ProGuard
אם אתה מכווץ את הקוד, עליך למנוע את הParcelable
,
Serializable
ו-Enum
שמות של מחלקות מערפול קוד (obfuscated) כחלק
תהליך ההקטנה. אפשר לעשות זאת באחת משתי הדרכים הבאות:
- להשתמש בהערות @Keep.
- להשתמש בכללי Keepname.
בקטעי המשנה הבאים מפורטות הגישות האלה.
שימוש בהערות @Keep
הדוגמה הבאה מוסיפה הערות @Keep
להגדרות של כיתה במודלים:
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 { ... }
שימוש בכללי Keepname
אפשר גם להוסיף כללים מסוג keepnames
לקובץ proguard-rules.pro
, כמו שמוצג
בדוגמה הבאה:
proGuard-כללים.pro
...
-keepnames class com.path.to.your.ParcelableArg
-keepnames class com.path.to.your.SerializableArg
-keepnames class com.path.to.your.EnumArg
...
מקורות מידע נוספים
מידע נוסף על הניווט זמין במאמרים הבאים: משאבים נוספים.