लिस्ट-डिटेल, यूज़र इंटरफ़ेस (यूआई) का एक पैटर्न है. इसमें दो पैनल वाला लेआउट होता है. एक पैनल में आइटम की सूची दिखती है, जबकि दूसरे पैनल में सूची से चुने गए आइटम की जानकारी दिखती है.
यह पैटर्न, उन ऐप्लिकेशन के लिए खास तौर पर काम का है जो बड़े कलेक्शन के एलिमेंट के बारे में ज़्यादा जानकारी देते हैं. उदाहरण के लिए, ईमेल क्लाइंट में ईमेल की सूची और हर ईमेल मैसेज का ब्यौरा दिखता है. लिस्ट-डिटेल का इस्तेमाल, कम अहम पाथ के लिए भी किया जा सकता है. जैसे, ऐप्लिकेशन की प्राथमिकताओं को कैटगरी की सूची में बांटना. साथ ही, हर कैटगरी की प्राथमिकताओं को जानकारी वाले पैनल में दिखाना.
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")
Groovy
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 ) } } ) } }