एक ऐप्लिकेशन डिज़ाइन करना बोझिल होता है और अक्सर एक व्हाइटबोर्ड होता है जिसमें विभिन्न बिंदुओं से दूसरों की ओर इशारा करते हुए तीर होते हैं।
आपने शुरुआत में सोचा था कि यह एक या दो एक्टिविटीज़ वाला ऐप्लिकेशन होगा, अचानक इसमें कई फ्लोज़, फ्रैगमेंट्स और यूज़र इंटरैक्शन की एक विस्तृत श्रृंखला दिखाई देती है। क्या यह अच्छा नहीं होगा यदि हम उस व्हाइटबोर्ड पर जो कुछ भी है उसे ले सकें और कोड में आसानी से दोहरा सकें?
Navigation Component को नमस्ते कहें।
अनजान लोगों के लिए, Navigation Component कोई अन्य UI क्लास नहीं है जिसे आप अपनी एक्टिविटी/फ्रैगमेंट के लिए लेआउट के बजाय रखते हैं। इसे एक नक्शे की तरह समझें, जहां महाद्वीपों के बजाय आपके पास आपके फ्रैगमेंट्स हैं, और आपको महाद्वीप से महाद्वीप तक जाने के लिए दिशानिर्देश की आवश्यकता होगी। यह आपके फ्रैगमेंट्स और उनके बीच के कनेक्शन्स को टॉप-डाउन तरीके से प्रस्तुत करता है। इस लेख में, हम इस कंपोनेंट के मुख्य पहलुओं पर जाएंगे और सीखेंगे कि हम इसे अपने ऐप्लिकेशन्स में कैसे इंटीग्रेट कर सकते हैं।
सेल सेट करने के लिए तैयार हैं? ⛵️
रस्सियाँ सीखना
Navigation Component Android Studio 3.3 और उसके बाद से उपलब्ध है। इसका उपयोग करने के लिए, अपने प्रोजेक्ट में निम्न डिपेंडेंसीज़ जोड़ें:
android { ... } dependencies { implementation 'androidx.navigation:navigation-fragment-ktx:2.0.0' implementation 'androidx.navigation:navigation-ui-ktx:2.0.0' }काम करने के लिए कुछ होने के लिए, आइए कल्पना करें कि हमने निम्न संरचना के साथ एक ऐप्लिकेशन डिज़ाइन किया है:
- Start Fragment
- Fragment A
- Fragment B
यूज़र Start फ्रैगमेंट से या तो Fragment A या Fragment B पर जा सकता है।

यदि हम यह सब Navigation Component के बिना करना चाहते हैं, तो हमें बटन क्लिक होने पर फ्रैगमेंट खोलने के लिए बहुत परिचित कोड जोड़ना होगा।
val myFragment : MyFragment = MyFragment() supportFragmentManager.beginTransaction().add(R.id.container, myFragment).commit()हमारे छोटे उदाहरण में, यह कई छोटी लाइनों तक सीमित है और काफी सरल है, लेकिन मुझे लगता है कि हम सभी सहमत हो सकते हैं कि यदि हमारा ऐप्लिकेशन बड़ा और अधिक जटिल यूज़र फ्लोज़ वाला होता तो यह उचित रूप से स्केल नहीं करेगा।
सब सवार
Navigation Component का उपयोग शुरू करने के लिए, हमें एक नेविगेशन ग्राफ बनाने की आवश्यकता है। यह ग्राफ हमारे नक्शे के रूप में कार्य करेगा, जो हमारे ऐप्लिकेशन में यूज़र फ्लो को रेखांकित करेगा। एक बनाने के लिए, res फोल्डर पर राइट क्लिक करें और एक नई रिसोर्स फ़ाइल बनाएं। हम इसका नाम रखेंगे: user_flow_graph.xml। फ़ाइल के प्रकार को Navigation के रूप में चिह्नित करना सुनिश्चित करें।

हर यात्रा एक होम बेस से शुरू होती है और हमारी भी अलग नहीं है। हमारा घर NavHost कहलाता है। यह डेस्टिनेशन्स के लिए एक प्लेसहोल्डर के रूप में कार्य करेगा जब यूज़र हमारे UI के साथ इंटरैक्ट करता है तो उन्हें स्वैप किया जाएगा। हमें NavHost को अपनी एक्टिविटी के मेन लेआउट में जोड़ने की आवश्यकता है:
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="https://schemas.android.com/apk/res/android" xmlns:tools="https://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:app="https://schemas.android.com/apk/res-auto" tools:context=".MainActivity"> <fragment android:id="@+id/nav_host_fragment" android:name="androidx.navigation.fragment.NavHostFragment" android:layout_width="0dp" android:layout_height="0dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent" app:defaultNavHost="true" app:navGraph="@navigation/user_flow_graph" /> </androidx.constraintlayout.widget.ConstraintLayout>हमने एक फ्रैगमेंट एलिमेंट जोड़ा है जो उस स्थान को रखेगा जहां हमारे फ्रैगमेंट्स प्रदर्शित और स्वैप किए जाएंगे। navGraph एट्रिब्यूट पर ध्यान दें, जिसे हमने अपनी पहले बनाई गई XML फ़ाइल से जोड़ा है।
अब हमें एक स्टार्टिंग डेस्टिनेशन जोड़ने की आवश्यकता है, क्योंकि यदि हम ऐसा नहीं करेंगे तो हमारा ऐप्लिकेशन कंपाइल नहीं होगा।
user_flow_graph.xml खुले होने पर, हमें नेविगेशन एडिटर में दिखाई देने वाले छोटे प्लस आइकन पर क्लिक करने की आवश्यकता है:

आप पॉप अप होने वाले मेनू में देख सकते हैं कि हम या तो एक प्लेसहोल्डर बना सकते हैं जिसे बाद में भरने की आवश्यकता होगी या हमारे पास मौजूद किसी भी फ्रैगमेंट को चुन सकते हैं:

हमारा यूज़र फ्लो हमारे Start Fragment से शुरू होता है, तो आइए पहले इसे चुनें।

आइए अपने अन्य दो फ्रैगमेंट्स, Fragment A और Fragment B को जोड़ें।

हम दो डेस्टिनेशन्स को उस डॉट पर क्लिक करके जोड़ते हैं जो तब दिखाई देता है जब हम एक डेस्टिनेशन पर होवर करते हैं और इसे दूसरे पर खींचते हैं।

हमने अभी Start Fragment और Fragment A और B के बीच जो बनाया है, वे एक्शन्स हैं।
शिवर मी टिम्बर्स
आपने खुद से पूछा होगा, यदि केवल डेस्टिनेशन्स को जोड़कर हमारा काम यहाँ पूरा हो गया है और किसी जादुई तरीके से सब कुछ काम करेगा।
खैर, ऐसा नहीं होगा।
हमें अपने कोड को डेस्टिनेशन पर नेविगेट करने के लिए बताने की आवश्यकता है। तो, हम ऐसा कैसे कर सकते हैं? इस प्रक्रिया में कुछ जादू शामिल है।
पहली चीज जो हम करने जा रहे हैं, वह है Safe Args नामक एक ग्रैडल प्लगइन जोड़ना। यह हमारे डेस्टिनेशन्स के बीच नेविगेट करते समय टाइप सेफ्टी सुनिश्चित करेगा।
buildscript { /... } dependencies { ... classpath "androidx.navigation:navigation-safe-args-gradle-plugin:2.0.0" } }हमें अपने ऐप्लिकेशन के build.gradle में निम्न प्लगइन भी जोड़ना होगा:
apply plugin: "androidx.navigation.safeargs.kotlin" साथ ही, सुनिश्चित करें कि आपकी gradle.properties फ़ाइल में android.useAndroidX=true है।
आगे बढ़ने से पहले, आइए समझें कि हमें इन सभी कॉन्फ़िगरेशन्स को जोड़ने की आवश्यकता क्यों थी। मूल रूप से, जब हमने पहले एक्शन्स बनाए थे, तो पर्दे के पीछे, Android Studio कोड जनरेट करता है जिसका उपयोग हम एक्शन्स को सक्रिय करने के लिए करेंगे। इस कोड में मेथड्स और क्लासेज होते हैं जो प्रत्येक एक्शन को दर्शाते हैं। आइए हमारे Start Fragment को उदाहरण के रूप में लें। हमारे द्वारा पहले घोषित एक्शन्स के लिए जनरेटेड कोड में StartFragmentDirections नामक एक क्लास होगी। इस क्लास के मेथड्स हमारे द्वारा पहले बनाए गए एक्शन्स को दर्शाते हैं। इसलिए हमारे दोनों फ्रैगमेंट्स के लिए, हमें मिलेगा:
- StartFragmentDirections.actionStartFragmentToFragmentA()
- StartFragmentDirections.actionStartFragmentToFragmentB()
अब जब हमारे एक्शन्स कोड में अनुवादित हो गए हैं, तो आइए उनका उपयोग करें:
val action = StartFragmentDirections.actionStartFragmentToFragmentA() इस प्रक्रिया में अंतिम चरण के लिए हमें NavController का उपयोग करने की आवश्यकता है। यह ऑब्जेक्ट हमारे NavHost के भीतर नेविगेशन को मैनेज करने का प्रभारी है। आप इसे इन तीन मेथड्स में से किसी एक का उपयोग करके एक्सेस कर सकते हैं:
- Fragment.findNavController()
- View.findNavController()
- Activity.findNavController(viewId: Int)
तो, एक साथ रखने पर हमारे पास होगा:
fragmentABtn.setOnClickListener { button -> val action = StartFragmentDirections.actionStartFragmentToFragmentA() button.findNavController().navigate(action) }अपने पाल ट्रिम करें
क्या होगा यदि हम अपने डेस्टिनेशन्स के बीच डेटा पास करना चाहते थे? एक परिदृश्य की कल्पना करें जहां यदि यूज़र किसी निश्चित आइटम पर क्लिक करता है, तो हम उस आइटम के साथ अपने अगले डेस्टिनेशन में कुछ करना चाहते हैं। इसके लिए, हमारे पास डेस्टिनेशन आर्गुमेंट्स हैं। हमारा user_flow_graph.xml खोलें और Fragment A पर क्लिक करें। आप दाईं ओर एक मेनू देखेंगे जो Fragment A के विभिन्न एट्रिब्यूट्स का विवरण देता है। उन एट्रिब्यूट्स में से एक Arguments होगा।

एक आर्गुमेंट जोड़ने के लिए, बस ➕ आइकन पर क्लिक करें। एक पॉपअप विंडो खुलती है और इसमें हम अपना आर्गुमेंट कॉन्फ़िगर कर सकते हैं। आप इसे एक नाम दे सकते हैं, इसका प्रकार चुन सकते हैं और एक डिफ़ॉल्ट मान जोड़ सकते हैं। आइए Fragment A में String प्रकार का एक आर्गुमेंट जोड़ें, जो Start Fragment से पास किया गया मैसेज होगा।

हमारे Start Fragment में, जहां हमने अपना एक्शन परिभाषित किया है और जनरेटेड मेथड को कॉल कर रहे हैं, हम अपना आर्गुमेंट पास करेंगे।
fragmentABtn.setOnClickListener { button -> val action = StartFragmentDirections.actionStartFragmentToFragmentA("Hello From Start Fragment") button.findNavController().navigate(action) }इसे Fragment A में एक्सेस करने के लिए, हमें या तो:
- बंडल एक्सेस करके और हमारे मैसेज वैल्यू को प्राप्त करके
class FragmentA: Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val bundle = arguments val root = inflater.inflate(R.layout.fragment_a, container, false) val textView : TextView = root.findViewById(R.id.textView) textView.text = bundle?.getString("message") return root } }- navArgs का उपयोग करें यदि हम -ktx डिपेंडेंसीज़ का उपयोग कर रहे हैं
class FragmentA: Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { val args : FragmentAArgs by navArgs() val root = inflater.inflate(R.layout.fragment_a, container, false) val textView : TextView = root.findViewById(R.id.textView) textView.text = args.message return root } }✋ navArgs का उपयोग करते समय, आपको अपने build.gradle फ़ाइल में Java8 के लिए सपोर्ट जोड़ने की आवश्यकता होगी।
यहां दिखाया गया सारा कोड इस GitHub रिपॉजिटरी में मिल सकता है।