नेविगेशन की मदद से, किसी डेस्टिनेशन के लिए आर्ग्युमेंट तय करके, नेविगेशन ऑपरेशन में डेटा अटैच किया जा सकता है. उदाहरण के लिए, उपयोगकर्ता प्रोफ़ाइल डेस्टिनेशन, उपयोगकर्ता आईडी के आधार पर यह तय कर सकता है कि किस उपयोगकर्ता को दिखाना है.
आम तौर पर, आपको डेस्टिनेशन के बीच कम से कम डेटा भेजना चाहिए. उदाहरण के लिए, किसी ऑब्जेक्ट को वापस पाने के लिए, आपको ऑब्जेक्ट के बजाय कुंजी पास करनी चाहिए. ऐसा इसलिए, क्योंकि Android पर सेव किए गए सभी स्टेटस के लिए कुल जगह सीमित होती है. अगर आपको ज़्यादा डेटा पास करना है, तो ViewModel की खास जानकारी में बताए गए तरीके के हिसाब से, ViewModel
का इस्तेमाल करें.
डेस्टिनेशन के आर्ग्युमेंट के बारे में बताएं
डेटा को एक डेस्टिनेशन से दूसरे डेस्टिनेशन पर भेजने के लिए, सबसे पहले आर्ग्युमेंट तय करें. इसके लिए, आर्ग्युमेंट को उस डेस्टिनेशन में जोड़ें जहां उसे भेजना है. इसके लिए, यह तरीका अपनाएं:
- नेविगेशन एडिटर में, उस डेस्टिनेशन पर क्लिक करें जिसे आर्ग्युमेंट मिलता है.
- एट्रिब्यूट पैनल में, जोड़ें (+) पर क्लिक करें.
- इसके बाद, दिखने वाली आर्ग्युमेंट लिंक जोड़ें विंडो में, आर्ग्युमेंट का नाम, आर्ग्युमेंट टाइप, और यह जानकारी डालें कि आर्ग्युमेंट में वैल्यू डालना ज़रूरी है या नहीं. साथ ही, ज़रूरत पड़ने पर डिफ़ॉल्ट वैल्यू डालें.
- जोड़ें पर क्लिक करें. ध्यान दें कि आर्ग्युमेंट अब एट्रिब्यूट पैनल में आर्ग्युमेंट सूची में दिखता है.
- इसके बाद, उस कार्रवाई पर क्लिक करें जो आपको इस डेस्टिनेशन पर ले जाती है. एट्रिब्यूट पैनल में, आपको अब आर्ग्युमेंट की डिफ़ॉल्ट वैल्यू सेक्शन में, जोड़ा गया नया आर्ग्युमेंट दिखेगा.
आपको यह भी दिख सकता है कि आर्ग्युमेंट को एक्सएमएल में जोड़ा गया था. एक्सएमएल व्यू पर टॉगल करने के लिए, टेक्स्ट टैब पर क्लिक करें. साथ ही, ध्यान दें कि आपका आर्ग्युमेंट उस डेस्टिनेशन में जोड़ा गया है जिसमें आर्ग्युमेंट मिलता है. इसका एक उदाहरण यहां दिया गया है:
<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" | हां - "सही" या "गलत" | हां | नहीं |
स्ट्रिंग | app:argType="string" | हां | हां | हां |
संसाधन का रेफ़रंस | app:argType="reference" | हां - डिफ़ॉल्ट वैल्यू, "@resourceType/resourceName" (उदाहरण के लिए, "@style/myCustomStyle") या "0" के तौर पर होनी चाहिए | हां | नहीं |
कस्टम Parcelable | app:argType="<type>", जहां <type>, Parcelable की पूरी तरह क्वालिफ़ाइड क्लास का नाम है |
"@null" की डिफ़ॉल्ट वैल्यू के साथ काम करता है. अन्य डिफ़ॉल्ट वैल्यू के साथ काम नहीं करता. | नहीं | हां |
कस्टम Serializable | app:argType="<type>", जहां <type>, Serializable की पूरी तरह क्वालिफ़ाइड क्लास का नाम है |
"@null" की डिफ़ॉल्ट वैल्यू के साथ काम करता है. अन्य डिफ़ॉल्ट वैल्यू के साथ काम नहीं करता. | नहीं | हां |
कस्टम Enum | app:argType="<type>", जहां <type>, Enum का पूरी तरह क्वालिफ़ाइड नाम है | हां - डिफ़ॉल्ट वैल्यू, बिना शर्त वाले नाम से मेल खानी चाहिए. उदाहरण के लिए, MyEnum.SUCCESS से मैच करने के लिए "SUCCESS". | नहीं | नहीं |
अगर किसी आर्ग्युमेंट टाइप में शून्य वैल्यू का इस्तेमाल किया जा सकता है, तो android:defaultValue="@null"
का इस्तेमाल करके, डिफ़ॉल्ट वैल्यू के तौर पर शून्य का एलान किया जा सकता है.
अपने आर्ग्युमेंट के साथ रूट, डीप लिंक, और यूआरआई को स्ट्रिंग से पार्स किया जा सकता है. जैसा कि पिछली टेबल में देखा गया है, Parcelables और Serializables जैसे कस्टम डेटा टाइप का इस्तेमाल करके ऐसा नहीं किया जा सकता. कस्टम जटिल डेटा को पास करने के लिए, डेटा को किसी दूसरी जगह सेव करें. जैसे, ViewModel या डेटाबेस. साथ ही, नेविगेट करते समय सिर्फ़ आइडेंटिफ़ायर पास करें. नेविगेशन पूरा होने के बाद, डेटा को नई जगह से वापस पाएं.
कस्टम टाइप में से किसी एक को चुनने पर, क्लास चुनें डायलॉग बॉक्स दिखता है. इसमें, आपको उस टाइप के लिए मिलती-जुलती क्लास चुनने के लिए कहा जाता है. प्रोजेक्ट टैब की मदद से, अपने मौजूदा प्रोजेक्ट से कोई क्लास चुनी जा सकती है.
<inferred type> चुनकर, नेविगेशन लाइब्रेरी को दी गई वैल्यू के आधार पर टाइप तय करने के लिए कहा जा सकता है.
कलेक्शन को चुनकर यह दिखाया जा सकता है कि आर्ग्युमेंट, चुने गए टाइप की वैल्यू का कलेक्शन होना चाहिए. यहां दी गई बातों का ध्यान रखें:
- एनम के ऐरे और रिसॉर्स रेफ़रंस के ऐरे काम नहीं करते.
- ऐरे में, शून्य वैल्यू का इस्तेमाल किया जा सकता है. भले ही, इस्तेमाल किए जा रहे टाइप में शून्य वैल्यू का इस्तेमाल किया जा सकता हो या नहीं. उदाहरण के लिए,
app:argType="integer[]"
का इस्तेमाल करने पर,app:nullable="true"
का इस्तेमाल करके यह बताया जा सकता है कि कोई शून्य ऐरे पास करना स्वीकार किया जा सकता है. - ऐरे में सिर्फ़ एक डिफ़ॉल्ट वैल्यू, "@null" का इस्तेमाल किया जा सकता है. ऐरे में कोई दूसरी डिफ़ॉल्ट वैल्यू नहीं दी जा सकती.
किसी ऐक्शन में डेस्टिनेशन आर्ग्युमेंट को बदलना
डेस्टिनेशन-लेवल के आर्ग्युमेंट और डिफ़ॉल्ट वैल्यू का इस्तेमाल, डेस्टिनेशन पर ले जाने वाली सभी कार्रवाइयों में किया जाता है. ज़रूरत पड़ने पर, ऐक्शन लेवल पर आर्ग्युमेंट तय करके, किसी आर्ग्युमेंट की डिफ़ॉल्ट वैल्यू को बदला जा सकता है. इसके अलावा, अगर आर्ग्युमेंट पहले से मौजूद नहीं है, तो उसे सेट भी किया जा सकता है. इस आर्ग्युमेंट का नाम और टाइप, डेस्टिनेशन में बताए गए आर्ग्युमेंट के नाम और टाइप से मेल खाना चाहिए.
यहां दिए गए एक्सएमएल में, एक ऐसी कार्रवाई के बारे में बताया गया है जिसमें एक आर्ग्युमेंट दिया गया है. यह आर्ग्युमेंट, पिछले उदाहरण में दिए गए डेस्टिनेशन-लेवल के आर्ग्युमेंट को बदल देता है:
<action android:id="@+id/startMyFragment"
app:destination="@+id/myFragment">
<argument
android:name="myArg"
app:argType="integer"
android:defaultValue="1" />
</action>
टाइप सेफ़्टी के साथ डेटा भेजने के लिए, Safe Args का इस्तेमाल करना
नेविगेशन कॉम्पोनेंट में Safe Args नाम का Gradle प्लग इन होता है. यह टाइप से सुरक्षित नेविगेशन और जुड़े आर्ग्युमेंट के ऐक्सेस के लिए, आसान ऑब्जेक्ट और बिल्डर क्लास जनरेट करता है. डेटा को नेविगेट करने और भेजने के लिए, Safe Args का सुझाव दिया जाता है, क्योंकि इससे टाइप सेफ़्टी बनी रहती है.
अगर Gradle का इस्तेमाल नहीं किया जा रहा है, तो SafeArgs प्लग इन का इस्तेमाल नहीं किया जा सकता. ऐसे मामलों में, सीधे डेटा पास करने के लिए, बंडल का इस्तेमाल किया जा सकता है.
अपने प्रोजेक्ट में 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
होना चाहिए.
Safe Args चालू करने के बाद, जनरेट किए गए कोड में हर कार्रवाई के लिए, यहां दी गई टाइप सेफ़ क्लास और तरीके शामिल होते हैं. साथ ही, ये हर भेजने और पाने वाले डेस्टिनेशन के साथ भी होते हैं.
हर उस डेस्टिनेशन के लिए एक क्लास बनाई जाती है जहां कोई ऐक्शन शुरू होता है. इस क्लास का नाम, ऑरिजिन डेस्टिनेशन का नाम होता है. इसमें "निर्देश" शब्द जोड़ा जाता है. उदाहरण के लिए, अगर ऑरिजिन डेस्टिनेशन
SpecifyAmountFragment
नाम का कोई फ़्रैगमेंट है, तो जनरेट की गई क्लास कोSpecifyAmountFragmentDirections
कहा जाता है.इस क्लास में, ऑरिजिन डेस्टिनेशन में तय किए गए हर ऐक्शन के लिए एक मेथड होता है.
आर्ग्युमेंट पास करने के लिए इस्तेमाल किए गए हर ऐक्शन के लिए, एक इनर क्लास बनाई जाती है, जिसका नाम ऐक्शन पर आधारित होता है. उदाहरण के लिए, अगर कार्रवाई का नाम
confirmationAction,
है, तो क्लास का नामConfirmationAction
होगा. अगर आपकी कार्रवाई मेंdefaultValue
के बिना आर्ग्युमेंट शामिल हैं, तो आर्ग्युमेंट की वैल्यू सेट करने के लिए, उससे जुड़ी ऐक्शन क्लास का इस्तेमाल करें.डेटा पाने वाले डेस्टिनेशन के लिए एक क्लास बनाई जाती है. इस क्लास का नाम, "Args" शब्द के साथ जोड़े गए डेस्टिनेशन का नाम होता है. उदाहरण के लिए, अगर डेस्टिनेशन फ़्रैगमेंट का नाम
ConfirmationFragment,
है, तो जनरेट की गई क्लास कोConfirmationFragmentArgs
कहा जाता है. आर्ग्युमेंट वापस पाने के लिए, इस क्लास केfromBundle()
तरीके का इस्तेमाल करें.
नीचे दिए गए उदाहरण में, इन तरीकों का इस्तेमाल करके आर्ग्युमेंट सेट करने और उसे 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); }
डेस्टिनेशन के कोड में, बंडल को वापस पाने और उसके कॉन्टेंट का इस्तेमाल करने के लिए, 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 का इस्तेमाल करना
ग्लोबल ऐक्शन के साथ Safe Args का इस्तेमाल करते समय, आपको अपने रूट <navigation>
एलिमेंट के लिए android:id
वैल्यू देनी होगी, जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है:
<?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>
नेविगेशन, <navigation>
एलिमेंट के लिए Directions
क्लास जनरेट करता है, जो android:id
वैल्यू पर आधारित होती है. उदाहरण के लिए, अगर आपके पास android:id=@+id/main_nav
वाला <navigation>
एलिमेंट है, तो जनरेट की गई क्लास को 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);
डेस्टिनेशन के कोड में, Bundle
को वापस पाने और उसके कॉन्टेंट का इस्तेमाल करने के लिए, getArguments()
तरीके का इस्तेमाल करें:
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
क्लास के नामों को उलझाने से रोकना होगा. ऐसा करने के दो तरीके हैं:
- @Keep एनोटेशन का इस्तेमाल करना.
- नामों को सेव रखने के नियमों का इस्तेमाल करें.
नीचे दिए गए सब-सेक्शन में इन तरीकों के बारे में बताया गया है.
@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 { ... }
'नामों को बनाए रखें' नियमों का इस्तेमाल करना
अपनी proguard-rules.pro
फ़ाइल में keepnames
नियम भी जोड़े जा सकते हैं, जैसा कि इस उदाहरण में दिखाया गया है:
proguard-rules.pro
...
-keepnames class com.path.to.your.ParcelableArg
-keepnames class com.path.to.your.SerializableArg
-keepnames class com.path.to.your.EnumArg
...
अन्य संसाधन
नेविगेशन के बारे में ज़्यादा जानने के लिए, यहां दिए गए अन्य संसाधन देखें.