लिस्ट-डिटेल, यूज़र इंटरफ़ेस (यूआई) का एक पैटर्न है. इसमें दो पैनल वाला लेआउट होता है. एक पैनल में आइटम की सूची दिखती है, जबकि दूसरे पैनल में सूची से चुने गए आइटम की जानकारी दिखती है.
यह पैटर्न, उन ऐप्लिकेशन के लिए खास तौर पर काम का है जो बड़ी कलेक्शन के एलिमेंट के बारे में ज़्यादा जानकारी देते हैं. उदाहरण के लिए, ईमेल क्लाइंट में ईमेल की सूची और हर ईमेल मैसेज का ब्यौरा दिखता है. सूची की जानकारी का इस्तेमाल, कम ज़रूरी पाथ के लिए भी किया जा सकता है. जैसे, ऐप्लिकेशन की सेटिंग को कैटगरी की सूची में बांटना. साथ ही, हर कैटगरी की सेटिंग को जानकारी वाले पैनल में दिखाना.
NavigableListDetailPaneScaffold की मदद से, लिस्ट-डिटेल पैटर्न लागू करना
NavigableListDetailPaneScaffold एक कंपोज़ेबल है. इसकी मदद से, Jetpack Compose में सूची की जानकारी लेआउट को आसानी से लागू किया जा सकता है. यह ListDetailPaneScaffold को रैप करता है. साथ ही, इसमें बिल्ट-इन नेविगेशन और पीछे जाने पर झलक दिखाने वाला हाथ का जेस्चर ऐनिमेशन जोड़े जाते हैं.
लिस्ट-डिटेल स्कैफ़ोल्ड में, ज़्यादा से ज़्यादा तीन पैनल हो सकते हैं:
- सूची वाला पैनल: इसमें आइटम का कलेक्शन दिखता है.
- जानकारी वाला पैनल: इसमें चुने गए आइटम की जानकारी दिखती है.
- अतिरिक्त पैनल (ज़रूरी नहीं): ज़रूरत पड़ने पर, इसमें अतिरिक्त जानकारी दिखती है.
स्कैफ़ोल्ड, विंडो के साइज़ के हिसाब से अडजस्ट होता है:
- बड़ी विंडो में, सूची और जानकारी वाले पैनल साथ-साथ दिखते हैं.
- छोटी विंडो में, एक बार में सिर्फ़ एक पैनल दिखता है. उपयोगकर्ता के नेविगेट करने पर, पैनल स्विच होते हैं.
डिपेंडेंसी का एलान करना
NavigableListDetailPaneScaffold Material 3 अडैप्टिव नेविगेशन
लाइब्रेरी का हिस्सा है.
अपने ऐप्लिकेशन या मॉड्यूल की build.gradle फ़ाइल में, ये तीन डिपेंडेंसी जोड़ें:
Kotlin
implementation("androidx.compose.material3.adaptive:adaptive") implementation("androidx.compose.material3.adaptive:adaptive-layout") implementation("androidx.compose.material3.adaptive:adaptive-navigation")
शानदार
implementation 'androidx.compose.material3.adaptive:adaptive' implementation 'androidx.compose.material3.adaptive:adaptive-layout' implementation 'androidx.compose.material3.adaptive:adaptive-navigation'
- adaptive: लो-लेवल बिल्डिंग ब्लॉक, जैसे कि
HingeInfoऔरPosture - adaptive-layout: अडैप्टिव लेआउट, जैसे कि
ListDetailPaneScaffoldऔरSupportingPaneScaffold - adaptive-navigation: पैनल के अंदर और उनके बीच नेविगेट करने के लिए कंपोज़ेबल. साथ ही, ऐसे अडैप्टिव लेआउट जो डिफ़ॉल्ट रूप से नेविगेशन की सुविधा देते हैं. जैसे,
NavigableListDetailPaneScaffoldऔरNavigableSupportingPaneScaffold
पक्का करें कि आपके प्रोजेक्ट में compose-material3-adaptive वर्शन 1.1.0-beta1 या इसके बाद का वर्शन शामिल हो.
प्रिडिक्टिव बैक जेस्चर के लिए ऑप्ट-इन करना
Android 15 या इससे पहले के वर्शन में, पीछे जाने पर झलक दिखाने वाला हाथ का जेस्चर ऐनिमेशन चालू करने के लिए, आपको पीछे जाने पर झलक दिखाने वाले हाथ के जेस्चर के लिए शामिल होना होगा. ऑप्ट-इन करने के लिए, अपनी AndroidManifest.xml फ़ाइल में मौजूद <application> टैग या
अलग-अलग <activity> टैग में
android:enableOnBackInvokedCallback="true" जोड़ें. ज़्यादा जानकारी के लिए, प्रिडिक्टिव बैक जेस्चर के लिए ऑप्ट-इन करना लेख पढ़ें.
जब आपका ऐप्लिकेशन, Android 16 (एपीआई लेवल 36) या इसके बाद के वर्शन को टारगेट करता है, तो पीछे जाने पर झलक दिखाने वाला हाथ का जेस्चर डिफ़ॉल्ट रूप से चालू हो जाता है.
बुनियादी इस्तेमाल
NavigableListDetailPaneScaffold को इस तरह लागू करें:
- चुने गए कॉन्टेंट को दिखाने वाली किसी क्लास का इस्तेमाल करें. चुने गए सूची आइटम को सेव और वापस लाने के लिए,
Parcelableक्लास का इस्तेमाल करें. आपके लिए कोड जनरेट करने के लिए, kotlin-parcelize प्लग-इन का इस्तेमाल करें. rememberListDetailPaneScaffoldNavigatorकी मदद से,ThreePaneScaffoldNavigatorबनाएं.
इस नेविगेटर का इस्तेमाल, सूची, जानकारी, और अतिरिक्त पैनल के बीच जाने के लिए किया जाता है. जेनेरिक टाइप का एलान करके, नेविगेटर स्कैफ़ोल्ड की स्थिति भी ट्रैक करता है. इसका मतलब है कि यह ट्रैक करता है कि कौनसी MyItem दिख रही है. पार्सल किए जा सकने वाले इस टाइप की स्थिति को, नेविगेटर सेव और वापस ला सकता है. इससे कॉन्फ़िगरेशन में होने वाले बदलावों को अपने-आप हैंडल किया जा सकता है.
नेविगेटर को
NavigableListDetailPaneScaffoldकंपोज़ेबल में पास करें.NavigableListDetailPaneScaffoldको, सूची वाले पैनल का अपना लागू किया गया वर्शन उपलब्ध कराएं. नेविगेशन के दौरान, पैनल के डिफ़ॉल्ट ऐनिमेशन लागू करने के लिए,AnimatedPaneका इस्तेमाल करें. इसके बाद, जानकारी वाले पैनल,ListDetailPaneScaffoldRole.Detailपर जाने और पास किए गए आइटम को दिखाने के लिए,ThreePaneScaffoldNavigatorका इस्तेमाल करें.NavigableListDetailPaneScaffoldमें, जानकारी वाले पैनल का अपना लागू किया गया वर्शन शामिल करें.
नेविगेशन पूरा होने के बाद, currentDestination में वह पैनल शामिल होता है जिस पर आपका ऐप्लिकेशन नेविगेट किया है. इसमें पैनल में दिखने वाला कॉन्टेंट भी शामिल होता है. contentKey प्रॉपर्टी, ओरिजनल कॉल में बताए गए टाइप की ही होती है. इसलिए, आपके पास दिखाने के लिए ज़रूरी किसी भी डेटा को ऐक्सेस करने का विकल्प होता है.
- ज़रूरी नहीं:
NavigableListDetailPaneScaffoldमें,defaultBackBehaviorबदलें. डिफ़ॉल्ट रूप से,NavigableListDetailPaneScaffold,defaultBackBehaviorके लिएPopUntilScaffoldValueChangeका इस्तेमाल करता है.
अगर आपके ऐप्लिकेशन के लिए, पीछे जाने के लिए किसी दूसरे नेविगेशन पैटर्न की ज़रूरत है, तो BackNavigationBehavior का कोई दूसरा विकल्प चुनकर, इस व्यवहार को बदला जा सकता है.
BackNavigationBehavior के विकल्प
इस सेक्शन में, ईमेल ऐप्लिकेशन का उदाहरण दिया गया है. इसमें एक पैनल में ईमेल की सूची और दूसरे पैनल में ईमेल की ज़्यादा जानकारी दिखती है.
PopUntilScaffoldValueChange (डिफ़ॉल्ट और ज़्यादातर मामलों में सुझाव दिया जाता है)
यह व्यवहार, पूरे लेआउट स्ट्रक्चर में होने वाले बदलावों पर फ़ोकस करता है. मल्टी-पैनल सेटअप में, जानकारी वाले पैनल में ईमेल का कॉन्टेंट बदलने से, उसके मूल लेआउट स्ट्रक्चर में कोई बदलाव नहीं होता. इसलिए, 'वापस जाएं' बटन दबाने पर, ऐप्लिकेशन या मौजूदा नेविगेशन ग्राफ़ से बाहर निकला जा सकता है. ऐसा इसलिए होता है, क्योंकि मौजूदा कॉन्टेक्स्ट में वापस जाने के लिए, लेआउट में कोई बदलाव नहीं किया गया है. सिंगल-पैनल लेआउट में, 'वापस जाएं' बटन दबाने पर, जानकारी वाले व्यू में कॉन्टेंट में होने वाले बदलावों को स्किप किया जाएगा और सूची वाले व्यू पर वापस जाया जाएगा. ऐसा इसलिए होता है, क्योंकि यह लेआउट में साफ़ तौर पर बदलाव दिखाता है.
यहां कुछ उदाहरण दिए गए हैं:
- मल्टी-पैनल: आप जानकारी वाले पैनल में कोई ईमेल (आइटम 1) देख रहे हैं. किसी दूसरे ईमेल (आइटम 2) पर क्लिक करने से, जानकारी वाला पैनल अपडेट हो जाता है. हालांकि, सूची और जानकारी वाले पैनल अब भी दिखते हैं. 'वापस जाएं' बटन दबाने पर, ऐप्लिकेशन या मौजूदा नेविगेशन फ़्लो से बाहर निकला जा सकता है.
- सिंगल-पैनल: आपने आइटम 1 देखा. इसके बाद, आइटम 2 देखा. 'वापस जाएं' बटन दबाने पर, सीधे ईमेल की सूची वाले पैनल पर वापस जाया जाएगा.
इसका इस्तेमाल तब करें, जब आपको यह दिखाना हो कि 'वापस जाएं' बटन दबाने पर, लेआउट में अलग-अलग ट्रांज़िशन होते हैं.
PopUntilContentChange
यह व्यवहार, दिखाए गए कॉन्टेंट को प्राथमिकता देता है. अगर आपने आइटम 1 देखा और उसके बाद आइटम 2 देखा, तो 'वापस जाएं' बटन दबाने पर, लेआउट के बावजूद आइटम 1 पर वापस जाया जाएगा.
यहां कुछ उदाहरण दिए गए हैं:
- मल्टी-पैनल: आपने जानकारी वाले पैनल में आइटम 1 देखा. इसके बाद, सूची में आइटम 2 पर क्लिक किया. जानकारी वाला पैनल अपडेट हो जाता है. 'वापस जाएं' बटन दबाने पर, जानकारी वाला पैनल आइटम 1 पर वापस आ जाएगा.
- सिंगल-पैनल: कॉन्टेंट में भी इसी तरह का बदलाव होता है.
इसका इस्तेमाल तब करें, जब उपयोगकर्ता को 'वापस जाएं' बटन दबाने पर, पहले देखे गए कॉन्टेंट पर वापस जाने की उम्मीद हो.
PopUntilCurrentDestinationChange
यह व्यवहार, मौजूदा नेविगेशन डेस्टिनेशन में बदलाव होने तक, बैक स्टैक को पॉप करता है. यह सिंगल और मल्टी-पैनल लेआउट, दोनों पर लागू होता है.
यहां कुछ उदाहरण दिए गए हैं:
चाहे आप सिंगल या मल्टी-पैनल लेआउट में हों, 'वापस जाएं' बटन दबाने पर, फ़ोकस हमेशा हाइलाइट किए गए नेविगेशन एलिमेंट से, पिछली डेस्टिनेशन पर चला जाएगा. हमारे ईमेल ऐप्लिकेशन में, इसका मतलब है कि चुने गए पैनल का विज़ुअल इंडिकेशन बदल जाएगा.
इसका इस्तेमाल तब करें, जब उपयोगकर्ता अनुभव के लिए, मौजूदा नेविगेशन का साफ़ विज़ुअल इंडिकेशन बनाए रखना ज़रूरी हो.
PopLatest
इस विकल्प से, बैकस्टैक से सिर्फ़ सबसे नई डेस्टिनेशन हटती है. इंटरमीडिएट स्थितियों को स्किप किए बिना, पीछे जाने के लिए इस विकल्प का इस्तेमाल करें.
इन चरणों को लागू करने के बाद, आपका कोड कुछ ऐसा दिखना चाहिए:
NavigableListDetailPaneScaffold( navigator = navigator, listPane = { AnimatedPane { ListContent( words = sampleWords, selectionState = navigator.currentDestination?.contentKey?.let { SelectionVisibilityState.ShowSelection(it) } ?: SelectionVisibilityState.NoSelection, onWordClick = { word -> scope.launch { navigator.navigateTo(ListDetailPaneScaffoldRole.Detail, word) } }, animatedVisibilityScope = this@AnimatedPane, sharedTransitionScope = this@SharedTransitionLayout ) } }, detailPane = { AnimatedPane { DetailContent( definedWord = navigator.currentDestination?.contentKey, animatedVisibilityScope = this@AnimatedPane, sharedTransitionScope = this@SharedTransitionLayout, onClosePane = { scope.launch { navigator.navigateBack( backNavigationBehavior = BackNavigationBehavior.PopUntilScaffoldValueChange ) } } ) } }