डेस्टिनेशन पर लॉजिक या रैपर लागू करना

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

कस्टम डेकोरेटर बनाना

डेकोरेटर बनाने के लिए, NavEntryDecorator क्लास को बढ़ाएं और इन तरीकों को बदलें:

  • decorate - यह एक कंपोज़ेबल लैम्डा है. इसे आपकी पिछली गतिविधियों में मौजूद हर NavEntry के लिए कॉल किया जाता है. इसे NavEntry को पैरामीटर के तौर पर मिलता है. इससे आपको ऐसे स्टेट ऑब्जेक्ट बनाने में मदद मिलती है जो एंट्री के contentKey के हिसाब से तय होते हैं. एंट्री के कॉन्टेंट के लिए डिपेंडेंसी देने के लिए, CompositionLocalProvider का इस्तेमाल किया जा सकता है. कॉन्टेंट को कंपोज़ेबल फ़ंक्शन से भी रैप किया जा सकता है या साइड-इफ़ेक्ट ट्रिगर किए जा सकते हैं. आपको हमेशा इस तरीके के अंदर entry.Content() को कॉल करना चाहिए.
  • onPop - यह एक कॉलबैक है. इसे तब शुरू किया जाता है, जब NavEntry को पिछली गतिविधियों से हटा दिया जाता है और कंपोज़िशन से बाहर कर दिया जाता है. इसे हटाई गई एंट्री का contentKey मिलता है. contentKey का इस्तेमाल करके, उस एंट्री से जुड़ी किसी भी स्थिति की पहचान करें और उसे ठीक करें.

यहां दिए गए उदाहरण में, NavEntryDecorator क्लास को बढ़ाकर कस्टम डेकोरेटर बनाया गया है.

// import androidx.navigation3.runtime.NavEntryDecorator
class CustomNavEntryDecorator<T : Any> : NavEntryDecorator<T>(
    decorate = { entry ->
        Log.d("CustomNavEntryDecorator", "entry with ${entry.contentKey} entered composition and was decorated")
        entry.Content()
    },
    onPop = { contentKey -> Log.d("CustomNavEntryDecorator", "entry with $contentKey was popped") }
)

अगर आपके डेकोरेटर को स्थिति का ऐक्सेस चाहिए, तो एक कंपोज़ेबल फ़ंक्शन बनाएं. यह फ़ंक्शन उस स्थिति को बनाता है. इसके बाद, इसका इस्तेमाल डेकोरेटर बनाने के लिए करें. उदाहरण के लिए, rememberSaveableStateHolderNavEntryDecorator का सोर्स कोड देखें. इससे स्थिति बनती है - एक SaveableStateHolder - और इसका इस्तेमाल डेकोरेटर बनाने के लिए किया जाता है.

पिछली ऐक्टिविटी को सजाना

NavEntryDecorator बनाने के बाद, अपने बैक स्टैक में मौजूद एंट्री को सजाएं. इसके लिए, इनमें से कोई एक तरीका अपनाएं:

  • rememberDecoratedNavEntries का इस्तेमाल करें. यह फ़ंक्शन तब काम आता है, जब आपके पास कई बैक स्टैक हों और हर बैक स्टैक के लिए डेकोरेटर का अपना सेट हो. ज़्यादा जानकारी के लिए, कोड की यह रेसिपी देखें. यह फ़ंक्शन, NavEntry की सजाई गई सूची दिखाता है. इसका इस्तेमाल NavDisplay के साथ किया जा सकता है.
  • entryDecorators पैरामीटर का इस्तेमाल करके, अपने डेकोरेटर को सीधे NavDisplay पर भेजें. NavDisplay कॉल rememberDecoratedNavEntries करता है और सजाई गई एंट्री दिखाता है.

डिफ़ॉल्ट डेकोरेटर शामिल करें

नेविगेशन 3 में, SaveableStateHolderNavEntryDecorator नाम का एक डिफ़ॉल्ट डेकोरेटर शामिल होता है. यह NavEntry की स्थिति को कॉन्फ़िगरेशन में बदलाव और प्रोसेस बंद होने के दौरान बनाए रखने की सुविधा देता है. यह NavEntry कॉन्टेंट को SaveableStateProvider के साथ रैप करता है. इससे NavEntry कॉन्टेंट में मौजूद rememberSaveable कॉल सही तरीके से काम कर पाते हैं.

अगर आपका डेकोरेटर SaveableStateProvider उपलब्ध नहीं करा रहा है, तो आपको दिए गए डेकोरेटर की सूची में SaveableStateHolderNavEntryDecorator को पहले डेकोरेटर के तौर पर शामिल करना चाहिए. इसे rememberSaveableStateHolderNavEntryDecorator का इस्तेमाल करके बनाया गया है.

उदाहरण के लिए:

// import androidx.navigation3.runtime.rememberSaveableStateHolderNavEntryDecorator
NavDisplay(
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        remember { CustomNavEntryDecorator() }
    ),
    // ...
)

ResultEventBusNavEntryDecorator का इस्तेमाल करके पास किए गए नतीजे

Navigation 3 1.2.0 से, ResultEventBusNavEntryDecorator का इस्तेमाल करके, हर NavEntry को ResultEventBus दिया जा सकता है. इसके लिए, LocalResultEventBus कंपोज़िशन लोकल का इस्तेमाल करें.

डिफ़ॉल्ट रूप से, rememberResultEventBusNavEntryDecorator rememberResultEventBus का इस्तेमाल करके, अंदरूनी तौर पर अपना ResultEventBus इंस्टेंस बनाता है और उसे याद रखता है. अगर आपको डेकोरेटर के क्रम से बाहर (जैसे, टॉप-लेवल ऐप्लिकेशन के स्केफ़ोल्डिंग में) इवेंट बस को ऐक्सेस करना है, तो ResultEventBus को ऊपर ले जाया जा सकता है. इसके लिए, rememberResultEventBus को कॉल करें और इसे rememberResultEventBusNavEntryDecorator(resultEventBus) को पास करें:

val resultEventBus = rememberResultEventBus()

NavDisplay(
    /* ... */
    entryDecorators = listOf(
        rememberSaveableStateHolderNavEntryDecorator(),
        rememberResultEventBusNavEntryDecorator(resultEventBus = resultEventBus)
    )
)

नतीजे भेजने और उन्हें देखने के बारे में ज़्यादा जानने के लिए, नतीजे दिखाना लेख पढ़ें.

डेकोरेटर का इस्तेमाल कब करना चाहिए

डेकोरेटर का इस्तेमाल इन कामों के लिए करें:

  • पिछली गतिविधियों में मौजूद हर NavEntry के लिए, डिपेंडेंसी बनाएं. उदाहरण के लिए, ViewModelStoreNavEntryDecorator हर NavEntry के लिए एक ViewModelStore बनाता है.
  • नतीजे पास करना और डेस्टिनेशन के बीच कम्यूनिकेट करना. उदाहरण के लिए, ResultEventBusNavEntryDecorator, पिछली गतिविधियों में मौजूद डेस्टिनेशन को ResultEventBus उपलब्ध कराता है.
  • किसी ऑब्जेक्ट को कई NavEntry के लिए स्कोप करें. उदाहरण के लिए, कई एंट्री के बीच ViewModel शेयर करने के लिए.
  • एक से ज़्यादा NavEntry के लिए एक ही कार्रवाई करें. उदाहरण के लिए, हर एंट्री के लिए लॉगिंग, डीबग करने या ट्रेस करने की कार्रवाइयां करना.
  • NavEntry को एक ही कंपोज़ेबल फ़ंक्शन के साथ रैप करें.
  • NavEntry से जुड़ी क्लीन अप की स्थिति. उदाहरण के लिए, जब पिछली गतिविधियों से किसी एंट्री को हटाया जाता है, तो ViewModelStoreNavEntryDecorator उससे जुड़े ViewModelStore को मिटा देता है.

डेकोरेटर का इस्तेमाल इन कामों के लिए न करें:

  • किसी एक NavEntry को डिपेंडेंसी पास करें.
  • ऐसी डिपेंडेंसी उपलब्ध कराएं जिनका स्कोप, पिछली गतिविधियों से ज़्यादा हो.

इन दोनों ही मामलों में, NavEntry बनाते समय सीधे तौर पर डिपेंडेंसी पास करें.

कोड के अन्य उदाहरणों के लिए, NavEntryDecorator देखें.