नेविगेशन से पता चलता है कि उपयोगकर्ता आपके ऐप्लिकेशन में कैसे घूमते हैं. उपयोगकर्ता, यूज़र इंटरफ़ेस (यूआई) के एलिमेंट के साथ इंटरैक्ट करते हैं. आम तौर पर, वे इन पर टैप या क्लिक करते हैं. इसके बाद, ऐप्लिकेशन नया कॉन्टेंट दिखाता है. अगर उपयोगकर्ता को पिछले कॉन्टेंट पर वापस जाना है, तो वे बैक जेस्चर का इस्तेमाल करते हैं या 'वापस जाएं' बटन पर टैप करते हैं.
नेविगेशन की स्थिति का मॉडल बनाना
इस व्यवहार का मॉडल बनाने का एक आसान तरीका, कॉन्टेंट का स्टैक बनाना है. जब उपयोगकर्ता नए कॉन्टेंट पर आगे जाता है, तो उसे स्टैक में सबसे ऊपर पुश कर दिया जाता है. जब वे उस कॉन्टेंट से वापस जाते हैं, तो उसे स्टैक से हटा दिया जाता है और पिछला कॉन्टेंट दिखने लगता है. नेविगेशन के हिसाब से, इस स्टैक को आम तौर पर बैक स्टैक कहा जाता है. ऐसा इसलिए, क्योंकि यह उस कॉन्टेंट को दिखाता है जिस पर उपयोगकर्ता वापस जा सकता है.
पिछली गतिविधियां बनाना
नेविगेशन 3 में, बैक स्टैक में असल में कॉन्टेंट नहीं होता. इसके बजाय, इसमें कॉन्टेंट के रेफ़रंस होते हैं. इन्हें कुंजियां कहा जाता है. कुंजियां किसी भी टाइप की हो सकती हैं, लेकिन आम तौर पर ये आसान, सीरियलाइज़ किए जा सकने वाले डेटा क्लास होती हैं. कॉन्टेंट के बजाय रेफ़रंस का इस्तेमाल करने के ये फ़ायदे हैं:
- बैक स्टैक में कुंजियां पुश करके, आसानी से नेविगेट किया जा सकता है.
- जब तक कुंजियों को सीरियलाइज़ किया जा सकता है, तब तक पिछली गतिविधियों को परसिस्टेंट स्टोरेज में सेव किया जा सकता है. इससे कॉन्फ़िगरेशन में बदलाव होने और ऐप्लिकेशन की प्रोसेस बंद होने पर भी, पिछली गतिविधियों का डेटा सुरक्षित रहता है. यह ज़रूरी है, क्योंकि उपयोगकर्ता उम्मीद करते हैं कि वे आपके ऐप्लिकेशन से बाहर निकलें, बाद में वापस आएं, और उसी कॉन्टेंट के साथ वहीं से शुरू करें जहां उन्होंने छोड़ा था. ज़्यादा जानकारी के लिए, अपनी पिछली गतिविधियां सेव करना लेख पढ़ें.
Navigation 3 API का एक अहम कॉन्सेप्ट यह है कि पिछली गतिविधियों का मालिकाना हक आपके पास होता है. लाइब्रेरी:
- उम्मीद करती है कि आपकी पिछली गतिविधियां, स्नैपशॉट-स्टेट बैकअप वाली
List<T>होगी. इसमेंTआपकी पिछली गतिविधियों कीkeysका टाइप है.Anyका इस्तेमाल किया जा सकता है या ज़्यादा मज़बूत टाइप वाली अपनी कुंजियां दी जा सकती हैं. जब आपको "पुश" या "पॉप" शब्द दिखते हैं, तो इसका मतलब है कि सूची के आखिर में आइटम जोड़े या हटाए जा रहे हैं. - आपकी पिछली गतिविधियों पर नज़र रखती है और यूज़र इंटरफ़ेस (यूआई) में इसकी स्थिति दिखाती है
NavDisplay.
यहां दिए गए उदाहरण में, कुंजियां और बैक स्टैक बनाने का तरीका बताया गया है. साथ ही, इसमें यह भी बताया गया है कि उपयोगकर्ता के नेविगेशन इवेंट के जवाब में, बैक स्टैक में कैसे बदलाव किए जाते हैं:
// Define keys that will identify content data object ProductList data class ProductDetail(val id: String) @Composable fun MyApp() { // Create a back stack, specifying the key the app should start with val backStack = remember { mutableStateListOf<Any>(ProductList) } // Supply your back stack to a NavDisplay so it can reflect changes in the UI // ...more on this below... // Push a key onto the back stack (navigate forward), the navigation library will reflect the change in state backStack.add(ProductDetail(id = "ABC")) // Pop a key off the back stack (navigate back), the navigation library will reflect the change in state backStack.removeLastOrNull() }
कुंजियों को कॉन्टेंट में बदलना
Navigation 3 में, कॉन्टेंट को NavEntry का इस्तेमाल करके मॉडल किया जाता है. यह एक क्लास है
, जिसमें कंपोज़ेबल फ़ंक्शन होता है. यह एक डेस्टिनेशन को दिखाता है. यह कॉन्टेंट का एक ऐसा हिस्सा है
जिस पर उपयोगकर्ता आगे और पीछे नेविगेट कर सकता है.
NavEntry में मेटाडेटा भी हो सकता है. यह कॉन्टेंट के बारे में जानकारी होती है. इस मेटाडेटा को कंटेनर ऑब्जेक्ट, जैसे कि NavDisplay पढ़ा जा सकता है. इससे उन्हें यह तय करने में मदद मिलती है कि NavEntry का कॉन्टेंट कैसे दिखाया जाए. उदाहरण के लिए, मेटाडेटा का इस्तेमाल, किसी खास NavEntry के लिए डिफ़ॉल्ट ऐनिमेशन को बदलने के लिए किया जा सकता है. NavEntry metadata, String कुंजियों से Any वैल्यू का मैप होता है. इससे डेटा को अलग-अलग तरीकों से सेव किया जा सकता है.
key को NavEntry में बदलने के लिए, एंट्री प्रोवाइडर बनाएं. यह एक ऐसा फ़ंक्शन है जो key को स्वीकार करता है और उस key के लिए NavEntry दिखाता है. आम तौर पर, इसे NavDisplay बनाते समय, लैम्डा पैरामीटर के तौर पर तय किया जाता है.
एंट्री प्रोवाइडर बनाने के दो तरीके हैं. पहला, सीधे तौर पर लैम्डा
फ़ंक्शन बनाकर और दूसरा, entryProvider DSL का इस्तेमाल करके.
सीधे तौर पर एंट्री प्रोवाइडर फ़ंक्शन बनाना
आम तौर पर, एंट्री प्रोवाइडर फ़ंक्शन बनाने के लिए, when स्टेटमेंट का इस्तेमाल किया जाता है. इसमें आपकी हर कुंजी के लिए एक ब्रांच होती है.
entryProvider = { key -> when (key) { is ProductList -> NavEntry(key) { Text("Product List") } is ProductDetail -> NavEntry( key, metadata = mapOf("extraDataKey" to "extraDataValue") ) { Text("Product ${key.id} ") } else -> { NavEntry(Unit) { Text(text = "Invalid Key: $it") } } } }
entryProvider DSL का इस्तेमाल करना
entryProvider DSL, आपके लैम्डा फ़ंक्शन को आसान बना सकता है. इसके लिए, आपको अपनी हर कुंजी के टाइप की जांच करने और हर टाइप के लिए NavEntry बनाने की ज़रूरत नहीं होती.
इसके लिए, entryProvider बिल्डर फ़ंक्शन का इस्तेमाल करें. इसमें डिफ़ॉल्ट फ़ॉलबैक बिहेवियर (गड़बड़ी दिखाना) भी शामिल होता है. यह तब होता है, जब कुंजी नहीं मिलती.
entryProvider = entryProvider { entry<ProductList> { Text("Product List") } entry<ProductDetail>( metadata = mapOf("extraDataKey" to "extraDataValue") ) { key -> Text("Product ${key.id} ") } }
स्निपेट से जुड़ी ये बातें ध्यान में रखें:
entryका इस्तेमाल, दिए गए टाइप और कंपोज़ेबल कॉन्टेंट के साथNavEntryतय करने के लिए किया जाता हैentryसेट करने के लिएmetadataपैरामीटर स्वीकार करता हैNavEntry.metadata
पिछली गतिविधियां दिखाना
बैक स्टैक, आपके ऐप्लिकेशन के नेविगेशन की स्थिति दिखाता है. जब भी बैक स्टैक में बदलाव होता है, तो ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) में, बैक स्टैक की नई स्थिति दिखनी चाहिए. Navigation 3 में, NavDisplay आपकी पिछली गतिविधियों पर नज़र रखता है और उसके हिसाब से यूज़र इंटरफ़ेस (यूआई) को अपडेट करता है. इसे इन पैरामीटर के साथ बनाएं:
- आपका बैक स्टैक - यह
SnapshotStateList<T>टाइप का होना चाहिए. इसमेंTआपके बैक स्टैक की कुंजियों का टाइप है. यह एक ऐसाListहै जिसे देखा जा सकता है. इसलिए, इसमें बदलाव होने पर,NavDisplayका कंपोज़िशन फिर से ट्रिगर होता है. - आपके पिछली गतिविधियां में मौजूद कुंजियों को
NavEntryऑब्जेक्ट में बदलने के लिए,entryProvider. - ज़रूरी नहीं,
onBackपैरामीटर के लिए लैम्डा उपलब्ध कराएं. जब उपयोगकर्ता, बैक इवेंट ट्रिगर करता है, तब इसे कॉल किया जाता है.
यहां दिए गए उदाहरण में, NavDisplay बनाने का तरीका बताया गया है.
data object Home data class Product(val id: String) @Composable fun NavExample() { val backStack = remember { mutableStateListOf<Any>(Home) } NavDisplay( backStack = backStack, onBack = { backStack.removeLastOrNull() }, entryProvider = { key -> when (key) { is Home -> NavEntry(key) { ContentGreen("Welcome to Nav3") { Button(onClick = { backStack.add(Product("123")) }) { Text("Click to navigate") } } } is Product -> NavEntry(key) { ContentBlue("Product ${key.id} ") } else -> NavEntry(Unit) { Text("Unknown route") } } } ) }
डिफ़ॉल्ट रूप से, NavDisplay, सिंगल पैन लेआउट में पिछली गतिविधियों पर सबसे ऊपर मौजूद NavEntry दिखाता है. यहां दी गई रिकॉर्डिंग में, यह ऐप्लिकेशन चलता हुआ दिख रहा है:
NavDisplay दो
डेस्टिनेशनडेस्टिनेशन की लाइफ़साइकल
NavDisplay कस्टम LifecycleOwners का इस्तेमाल करके, सीन-लेवल और एंट्री-लेवल
, दोनों तरह की पाबंदियों के आधार पर,
NavEntry की लाइफ़साइकल की स्थिति को सीमित करता है.
Compose में लाइफ़साइकल के बारे में ज़्यादा जानकारी के लिए, Jetpack Compose में लाइफ़साइकल देखें.
सीन-लेवल लाइफ़साइकल की पाबंदियां
NavDisplay, चालू Scene की लाइफ़साइकल मैनेज करता है. सीन-लेवल की पाबंदियां इस तरह तय की जाती हैं:
नॉन-ओवरले सीन के लिए:
RESUMED: इसकी अनुमति सिर्फ़ तब दी जाती है, जब सीन ट्रांज़िशन सेटल हो गया हो और उसके ऊपर कोई चालू ओवरले सीन न दिख रहा हो.STARTED: सीन ट्रांज़िशन के दौरान, इसेSTARTEDपर सीमित किया जाता है. जैसे, आगे या पीछे नेविगेट करते समय या जब यह किसी ओवरले से कवर हो.
डायलॉग या बॉटम शीट जैसे ओवरले सीन के लिए:
RESUMED: इसकी अनुमति सिर्फ़ सबसे ऊपर मौजूद, फ़िलहाल चालू ओवरले सीन के लिए दी जाती है.STARTED: इसके नीचे मौजूद उन ओवरले सीन के लिए, इसेSTARTEDपर सीमित किया जाता है जो किसी नए ओवरले से कवर हैं.
एंट्री-लेवल लाइफ़साइकल की स्थिति
लाइब्रेरी, पिछली गतिविधियों में मौजूद हर NavEntry की ज़्यादा से ज़्यादा लाइफ़साइकल की स्थिति को मैनेज करती है:
RESUMED: अगर एंट्री, मौजूदा पिछली गतिविधियों में मौजूद है, तो उसकी लाइफ़साइकल कोRESUMEDतक जाने की अनुमति दी जाती है. हालांकि, यह सीन-लेवल की पाबंदी के हिसाब से तय होता है.CREATED: अगर एंट्री अब बैक स्टैक में नहीं है, जैसे कि उसे पॉप किया गया है, लेकिन ऐनिमेशन के दौरान वह अब भी स्क्रीन पर दिख रही है, तो लाइब्रेरी उसकी लाइफ़साइकल कोCREATEDपर सीमित करती है. इस सीमा से यह पक्का होता है कि बैकग्राउंड या बाहर निकलने वाली एंट्री, चालू काम करना बंद कर दें. जैसे, फ़्लो इकट्ठा करना याRESUMEDयाSTARTEDस्थितियों से जुड़े कोरोटीन लॉन्च करना. ऐसा तब होता है, जब वे अपने ट्रांज़िशन पूरे कर लेती हैं.
ये दोनों एक साथ कैसे काम करती हैं
उदाहरण के लिए, NavEntry की लाइफ़साइकल की आखिरी स्थिति इस तरह तय की जाती है:
| परिदृश्य | सीन-लेवल की पाबंदी | एंट्री-लेवल की पाबंदी | लागू होने वाली पाबंदी |
|---|---|---|---|
| चालू एंट्री, सेटल स्क्रीन (कोई ट्रांज़िशन या ओवरले नहीं) | RESUMED |
RESUMED |
RESUMED |
| चालू एंट्री, ट्रांज़िशन के दौरान (नेविगेट करना) | STARTED |
RESUMED |
STARTED |
| चालू एंट्री, किसी ओवरले से कवर (उदाहरण के लिए, कोई डायलॉग खुला है) | STARTED |
RESUMED |
STARTED |
| पॉप की गई एंट्री, ऐनिमेशन के दौरान बाहर निकल रही है | STARTED या RESUMED |
CREATED |
CREATED |
जानकारी को एक जगह इकट्ठा किया जा रहा है
यहां दिए गए डायग्राम में दिखाया गया है कि Navigation 3 में, अलग-अलग ऑब्जेक्ट के बीच डेटा कैसे फ़्लो होता है:
नेविगेशन इवेंट से बदलाव शुरू होते हैं. उपयोगकर्ता के इंटरैक्शन के जवाब में, बैक स्टैक में कुंजियां जोड़ी या हटाई जाती हैं.
पिछली गतिविधियों की स्थिति में बदलाव होने पर, कॉन्टेंट वापस पाया जाता है.
NavDisplay(एक कंपोज़ेबल, जो पिछली गतिविधियां रेंडर करता है) पिछली गतिविधियों पर नज़र रखता है. डिफ़ॉल्ट कॉन्फ़िगरेशन में, यह सिंगल पैन लेआउट में सबसे ऊपर मौजूद बैक स्टैक एंट्री दिखाता है. जब पिछली गतिविधियों पर सबसे ऊपर मौजूद कुंजी बदलती है, तोNavDisplayइस कुंजी का इस्तेमाल करके, एंट्री प्रोवाइडर से उससे जुड़ा कॉन्टेंट का अनुरोध करता है.एंट्री प्रोवाइडर, कॉन्टेंट उपलब्ध कराता है. एंट्री प्रोवाइडर एक ऐसा फ़ंक्शन है जो कुंजी को
NavEntryमें बदलता है.NavDisplayसे कुंजी मिलने पर, एंट्री प्रोवाइडर उससे जुड़ाNavEntryउपलब्ध कराता है. इसमें कुंजी और कॉन्टेंट, दोनों शामिल होते हैं.कॉन्टेंट दिखाया जाता है.
NavDisplay,NavEntryको स्वीकार करता है और कॉन्टेंट दिखाता है.