बुनियादी बातों को समझना और उन्हें लागू करना

नेविगेशन से पता चलता है कि उपयोगकर्ता आपके ऐप्लिकेशन में कैसे घूमते हैं. उपयोगकर्ता, यूज़र इंटरफ़ेस (यूआई) के एलिमेंट के साथ इंटरैक्ट करते हैं. आम तौर पर, वे इन पर टैप या क्लिक करते हैं. इसके बाद, ऐप्लिकेशन नया कॉन्टेंट दिखाता है. अगर उपयोगकर्ता को पिछले कॉन्टेंट पर वापस जाना है, तो वे बैक जेस्चर का इस्तेमाल करते हैं या 'वापस जाएं' बटन पर टैप करते हैं.

नेविगेशन की स्थिति का मॉडल बनाना

इस व्यवहार का मॉडल बनाने का एक आसान तरीका, कॉन्टेंट का स्टैक बनाना है. जब उपयोगकर्ता नए कॉन्टेंट पर आगे जाता है, तो उसे स्टैक में सबसे ऊपर पुश कर दिया जाता है. जब वे उस कॉन्टेंट से वापस जाते हैं, तो उसे स्टैक से हटा दिया जाता है और पिछला कॉन्टेंट दिखने लगता है. नेविगेशन के हिसाब से, इस स्टैक को आम तौर पर बैक स्टैक कहा जाता है. ऐसा इसलिए, क्योंकि यह उस कॉन्टेंट को दिखाता है जिस पर उपयोगकर्ता वापस जा सकता है.

सॉफ़्टवेयर कीबोर्ड के ऐक्शन बटन (सही का निशान वाला आइकॉन) की इमेज. इस आइकॉन को लाल रंग के गोले में दिखाया गया है.
पहली इमेज. इस डायग्राम में दिखाया गया है कि उपयोगकर्ता के नेविगेशन इवेंट के हिसाब से, बैक स्टैक में कैसे बदलाव होते हैं.

पिछली गतिविधियां बनाना

नेविगेशन 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 दो डेस्टिनेशन
के साथ, डिफ़ॉल्ट बिहेवियर.

डेस्टिनेशन की लाइफ़साइकल

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 में, अलग-अलग ऑब्जेक्ट के बीच डेटा कैसे फ़्लो होता है:

इस इमेज में, Navigation 3 में मौजूद अलग-अलग ऑब्जेक्ट के बीच डेटा के फ़्लो को दिखाया गया है.
तीसरी इमेज. इस डायग्राम में दिखाया गया है कि Navigation 3 में, अलग-अलग ऑब्जेक्ट के बीच डेटा कैसे फ़्लो होता है.
  1. नेविगेशन इवेंट से बदलाव शुरू होते हैं. उपयोगकर्ता के इंटरैक्शन के जवाब में, बैक स्टैक में कुंजियां जोड़ी या हटाई जाती हैं.

  2. पिछली गतिविधियों की स्थिति में बदलाव होने पर, कॉन्टेंट वापस पाया जाता है. NavDisplay (एक कंपोज़ेबल, जो पिछली गतिविधियां रेंडर करता है) पिछली गतिविधियों पर नज़र रखता है. डिफ़ॉल्ट कॉन्फ़िगरेशन में, यह सिंगल पैन लेआउट में सबसे ऊपर मौजूद बैक स्टैक एंट्री दिखाता है. जब पिछली गतिविधियों पर सबसे ऊपर मौजूद कुंजी बदलती है, तो NavDisplay इस कुंजी का इस्तेमाल करके, एंट्री प्रोवाइडर से उससे जुड़ा कॉन्टेंट का अनुरोध करता है.

  3. एंट्री प्रोवाइडर, कॉन्टेंट उपलब्ध कराता है. एंट्री प्रोवाइडर एक ऐसा फ़ंक्शन है जो कुंजी को NavEntry में बदलता है. NavDisplay से कुंजी मिलने पर, एंट्री प्रोवाइडर उससे जुड़ा NavEntry उपलब्ध कराता है. इसमें कुंजी और कॉन्टेंट, दोनों शामिल होते हैं.

  4. कॉन्टेंट दिखाया जाता है. NavDisplay, NavEntry को स्वीकार करता है और कॉन्टेंट दिखाता है.