कई ऐप्लिकेशन को आइटम के संग्रह दिखाने की ज़रूरत होती है. इस दस्तावेज़ में बताया गया है कि की मदद से Jetpack Compose में तेज़ी से ऐसा किया जा सकता है.
अगर आपको पता है कि आपके इस्तेमाल के उदाहरण के लिए स्क्रोल करने की ज़रूरत नहीं है, तो
निर्देश के आधार पर, किसी आसान Column
या Row
का इस्तेमाल करें. साथ ही, हर आइटम का कॉन्टेंट
सूची में नीचे दिए गए तरीके से दोहराना:
@Composable fun MessageList(messages: List<Message>) { Column { messages.forEach { message -> MessageRow(message) } } }
हम verticalScroll()
मॉडिफ़ायर का इस्तेमाल करके, Column
को स्क्रोल करने लायक बना सकते हैं.
लेज़ी लिस्ट
अगर आपको बड़ी संख्या में आइटम (या अज्ञात लंबाई की सूची) दिखाने की ज़रूरत है, तो
Column
जैसे लेआउट का इस्तेमाल करने से, परफ़ॉर्मेंस से जुड़ी समस्याएं हो सकती हैं. ऐसा इसलिए, क्योंकि सभी आइटम मिलकर तय किए जाएंगे और तय किए जाएंगे कि वे दिख रहे हैं या नहीं.
Compose, कॉम्पोनेंट का एक सेट उपलब्ध कराता है. इससे सिर्फ़ ऐसे आइटम तैयार होते हैं और लेआउट किए जाते हैं
कॉम्पोनेंट के व्यूपोर्ट में दिखती हैं. इन कॉम्पोनेंट में ये शामिल हैं
LazyColumn
और
LazyRow
.
जैसा कि नाम से ही पता चलता है,
LazyColumn
और
LazyRow
वह ओरिएंटेशन है जिसमें वे अपने आइटम लेआउट करते हैं और स्क्रोल करते हैं. LazyColumn
वर्टिकल स्क्रोलिंग सूची बनाता है और LazyRow
हॉरिज़ॉन्टल तौर पर स्क्रोल करता है
स्क्रोलिंग सूची.
Compose में ज़्यादातर लेआउट से लेज़ी कॉम्पोनेंट अलग होते हैं. इसके बजाय
कॉन्टेंट ब्लॉक करने के @Composable
पैरामीटर को स्वीकार किया जा रहा है, जिससे ऐप्लिकेशन सीधे तौर पर
कंपोज़ेबल का इस्तेमाल करते हैं, तो लेज़ी कॉम्पोनेंट एक LazyListScope.()
ब्लॉक देते हैं. यह
LazyListScope
ब्लॉक एक डीएसएल सुविधा देता है, जिसकी मदद से ऐप्लिकेशन, आइटम के कॉन्टेंट के बारे में जानकारी दे सकते हैं. कॉन्टेंट बनाने
इसके बाद, लेज़ी कॉम्पोनेंट को हर आइटम के कॉन्टेंट को
लेआउट और स्क्रोल पोज़िशन के हिसाब से ज़रूरी है.
LazyListScope
डीएसएल
LazyListScope
का डीएसएल, आइटम के बारे में जानकारी देने के लिए कई फ़ंक्शन देता है
का इस्तेमाल करें. सबसे बुनियादी बातों में,
item()
एक आइटम जोड़ता है और
items(Int)
एकाधिक आइटम जोड़ता है:
LazyColumn { // Add a single item item { Text(text = "First item") } // Add 5 items items(5) { index -> Text(text = "Item: $index") } // Add another single item item { Text(text = "Last item") } }
ऐसे कई एक्सटेंशन फ़ंक्शन भी हैं जिनकी मदद से,
आइटम का संग्रह, जैसे कि List
. इन एक्सटेंशन से हम आसानी से
ऊपर दिए गए हमारे Column
उदाहरण को माइग्रेट करें:
/** * import androidx.compose.foundation.lazy.items */ LazyColumn { items(messages) { message -> MessageRow(message) } }
इसका एक वैरिएंट यह भी है
items()
एक्सटेंशन फ़ंक्शन को कॉल किया गया
itemsIndexed()
,
जिससे इंडेक्स होता है. कृपया
LazyListScope
का संदर्भ देखें.
लेज़ी ग्रिड
कॉन्टेंट बनाने
LazyVerticalGrid
और
LazyHorizontalGrid
कंपोज़ेबल का इस्तेमाल करके ग्रिड में आइटम दिखाए जा सकते हैं. लेज़ी वर्टिकल ग्रिड
अपने आइटम को वर्टिकल तौर पर स्क्रोल किए जा सकने वाले कंटेनर में दिखाएगा, जो
एक से ज़्यादा कॉलम में वैल्यू होंगी, जबकि लेज़ी हॉरिज़ॉन्टल ग्रिड का व्यवहार एक जैसा होगा
आदी है.
ग्रिड में एपीआई की उतनी ही असरदार सुविधाएं होती हैं जैसे कि लिस्ट में होती हैं. साथ ही, वे
बहुत मिलता-जुलता डीएसएल -
LazyGridScope.()
का इस्तेमाल करें.
इसमें columns
पैरामीटर
LazyVerticalGrid
और rows
पैरामीटर,
LazyHorizontalGrid
यह कंट्रोल किया जा सकता है कि सेल को कॉलम या पंक्तियों में कैसे बनाया जाए. नीचे दिए गए
उदाहरण, आइटम को ग्रिड में दिखाता है.
GridCells.Adaptive
हर कॉलम की चौड़ाई कम से कम 128.dp
पर सेट करने के लिए:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(photos) { photo -> PhotoItem(photo) } }
LazyVerticalGrid
की मदद से, आइटम के लिए चौड़ाई तय की जा सकती है. इसके बाद, ग्रिड
जितने चाहें उतने कॉलम में फ़िट हो जाते हैं. बाकी बची चौड़ाई को बराबर-बराबर बांटा जाएगा
की गणना करने के बाद, कॉलम की संख्या की गणना की जाती है.
साइज़ का यह आसान तरीका, आइटम के सेट को दिखाने में खास तौर पर मददगार होता है
सकता है.
अगर आपको इस्तेमाल किए जाने वाले कॉलम की सटीक संख्या पता है, तो
का इंस्टेंस
GridCells.Fixed
जिसमें ज़रूरी कॉलम की संख्या मौजूद है.
अगर आपके डिज़ाइन में नॉन-स्टैंडर्ड डाइमेंशन वाले कुछ ही आइटम की ज़रूरत है, तो
आइटम के लिए कस्टम कॉलम स्पैन देने के लिए, ग्रिड सहायता का इस्तेमाल किया जा सकता है.
कॉलम अवधि इस विकल्प के span
पैरामीटर के साथ तय करें
LazyGridScope DSL
item
और items
तरीके.
maxLineSpan
स्पैन स्कोप की एक वैल्यू, खास तौर पर तब काम आती है, जब
अडैप्टिव साइज़िंग की सुविधा, क्योंकि कॉलम की संख्या तय नहीं होती है.
इस उदाहरण में, लाइन का पूरा हिस्सा देने का तरीका बताया गया है:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 30.dp) ) { item(span = { // LazyGridItemSpanScope: // maxLineSpan GridItemSpan(maxLineSpan) }) { CategoryCard("Fruits") } // ... }
लेज़ी स्टेज्ड ग्रिड
LazyVerticalStaggeredGrid
और
LazyHorizontalStaggeredGrid
ऐसे कंपोज़ेबल होते हैं जिनकी मदद से आप आइटम के लेज़ी-लोडेड, स्टेज किए गए ग्रिड बना सकते हैं.
लेज़ी वर्टिकल स्टेज्ड ग्रिड, अपने आइटम को वर्टिकल तरीके से स्क्रोल करते हुए दिखाता है
कंटेनर, जो कई कॉलम में फैला होता है और जिसकी सहायता से अलग-अलग आइटम
अलग-अलग ऊंचाई पर. लेज़ी हॉरिज़ॉन्टल ग्रिड,
अलग-अलग चौड़ाई वाले आइटम वाला हॉरिज़ॉन्टल ऐक्सिस.
यहां दिया गया स्निपेट, LazyVerticalStaggeredGrid
के इस्तेमाल का बुनियादी उदाहरण है
हर आइटम के लिए 200.dp
चौड़ाई के साथ:
LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Adaptive(200.dp), verticalItemSpacing = 4.dp, horizontalArrangement = Arrangement.spacedBy(4.dp), content = { items(randomSizedPhotos) { photo -> AsyncImage( model = photo, contentScale = ContentScale.Crop, contentDescription = null, modifier = Modifier.fillMaxWidth().wrapContentHeight() ) } }, modifier = Modifier.fillMaxSize() )
कॉलम की तय संख्या सेट करने के लिए,
StaggeredGridCells.Adaptive
के बजाय StaggeredGridCells.Fixed(columns)
.
यह उपलब्ध चौड़ाई को कॉलम (या
हॉरिज़ॉन्टल ग्रिड होता है और हर आइटम उस चौड़ाई (या
हॉरिज़ॉन्टल ग्रिड):
LazyVerticalStaggeredGrid( columns = StaggeredGridCells.Fixed(3), verticalItemSpacing = 4.dp, horizontalArrangement = Arrangement.spacedBy(4.dp), content = { items(randomSizedPhotos) { photo -> AsyncImage( model = photo, contentScale = ContentScale.Crop, contentDescription = null, modifier = Modifier.fillMaxWidth().wrapContentHeight() ) } }, modifier = Modifier.fillMaxSize() )
![Compose में इमेज की लेज़ी स्टैग की गई ग्रिड](https://developer.android.com/static/develop/ui/compose/images/lists/staggered_grid_fixed.png?authuser=6&hl=hi)
कॉन्टेंट पैडिंग
कभी-कभी आपको कॉन्टेंट के किनारों के आस-पास पैडिंग (जगह) जोड़ने की ज़रूरत पड़ सकती है. द लेज़ी
कॉम्पोनेंट से आपको यह तय करने में मदद मिलती है कि
PaddingValues
contentPadding
पैरामीटर की मदद से यह काम कर सकता है:
LazyColumn( contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), ) { // ... }
इस उदाहरण में, हम हॉरिज़ॉन्टल किनारों पर पैडिंग (जगह) के 16.dp
को जोड़ते हैं (बाएं और
दायां) और फिर कॉन्टेंट के सबसे ऊपर और सबसे नीचे 8.dp
.
कृपया ध्यान दें कि यह पैडिंग कॉन्टेंट पर लागू होती है, न कि
LazyColumn
खुद. ऊपर दिए गए उदाहरण में, पहला आइटम 8.dp
जोड़ेगा
सबसे ऊपर की ओर पैडिंग (जगह), आखिरी आइटम 8.dp
को उसके नीचे और सभी आइटम को जोड़ देगा
बाईं और दाईं ओर 16.dp
पैडिंग होगी.
कॉन्टेंट के बीच स्पेस
आइटम के बीच स्पेस जोड़ने के लिए, इनका इस्तेमाल किया जा सकता है
Arrangement.spacedBy()
.
नीचे दिए गए उदाहरण में हर आइटम के बीच 4.dp
की जगह जोड़ी गई है:
LazyColumn( verticalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
इसी तरह LazyRow
के लिए:
LazyRow( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
हालांकि ग्रिड, वर्टिकल और हॉरिज़ॉन्टल, दोनों तरह से स्वीकार किए जाते हैं:
LazyVerticalGrid( columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(photos) { item -> PhotoItem(item) } }
आइटम कुंजियां
डिफ़ॉल्ट रूप से, हर आइटम की स्थिति को
सूची या ग्रिड. हालांकि, अगर डेटा सेट में बदलाव होता है, तो इसकी वजह से समस्याएं हो सकती हैं, क्योंकि
स्थिति बदलने के दौरान याद रखी गई कोई भी स्थिति मिटा दी जाती है. अगर आपको लगता है कि
LazyColumn
में LazyRow
की स्थिति, अगर लाइन में आइटम की पोज़िशन बदलती है, तो
फिर उपयोगकर्ता पंक्ति में अपनी स्क्रोल करने की जगह खो देगा.
इससे बचने के लिए, हर आइटम को एक यूनीक और स्थायी कुंजी दी जा सकती है. इसके लिए,
key
पैरामीटर के लिए ब्लॉक. स्थिर कुंजी उपलब्ध कराने से, आइटम की स्थिति
डेटा सेट में होने वाले बदलावों के मुताबिक:
LazyColumn { items( items = messages, key = { message -> // Return a stable + unique key for the item message.id } ) { message -> MessageRow(message) } }
कुंजियां उपलब्ध कराने से, Compose की सुविधा में आपके ऑर्डर का क्रम सही से मैनेज करने में मदद मिलती है. उदाहरण के लिए, अगर आपके आइटम में याद रखी गई स्थिति शामिल है, तो कुंजियों को सेट करने से जब आइटम की स्थिति बदल जाती है, तो इस स्थिति को आइटम के साथ ले जाने के लिए लिखें.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = remember { Random.nextInt() } } }
हालांकि, आइटम बटन के तौर पर किस टाइप का इस्तेमाल किया जा सकता है, इसकी एक सीमा तय है.
कुंजी के टाइप के साथ काम करना ज़रूरी है
Bundle
, Android का वह तरीका जो
यह जानकारी दिखाता है कि गतिविधि को कब फिर से बनाया गया. Bundle
, प्रिमिटिव जैसे टाइप के साथ काम करता है
enum या पार्सलेबल.
LazyColumn { items(books, key = { // primitives, enums, Parcelable, etc. }) { // ... } }
कुंजी Bundle
के साथ काम करनी चाहिए, ताकि rememberSaveable
कंपोज़ेबल गतिविधि को फिर से बनाए जाने पर, उसे वापस लाया जा सकता है या
इस आइटम से दूर स्क्रोल करके वापस स्क्रोल करें.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = rememberSaveable { Random.nextInt() } } }
आइटम पर आधारित ऐनिमेशन
अगर आपने RecyclerView विजेट का इस्तेमाल किया है, तो आपको पता चल जाएगा कि वह आइटम को ऐनिमेट करता है
बदलाव अपने-आप हो जाता है.
आइटम का क्रम बदलने के लिए, लेज़ी लेआउट में एक जैसी सुविधाएं उपलब्ध होती हैं.
यह एपीआई इस्तेमाल में आसान है - आपको सिर्फ़ इसे सेट करना होगा
animateItemPlacement
आइटम कॉन्टेंट का मॉडिफ़ायर:
LazyColumn { items(books, key = { it.id }) { Row(Modifier.animateItemPlacement()) { // ... } } }
ज़रूरत पड़ने पर, कस्टम ऐनिमेशन स्पेसिफ़िकेशन भी दिए जा सकते हैं:
LazyColumn { items(books, key = { it.id }) { Row( Modifier.animateItemPlacement( tween(durationMillis = 250) ) ) { // ... } } }
पक्का करें कि आपने अपने आइटम की कुंजियां दी हों, ताकि नई चीज़ें ढूंढी जा सकें स्थानांतरित तत्व के लिए स्थिति.
क्रम बदलने के अलावा, जोड़ने और हटाने के लिए आइटम ऐनिमेशन फ़िलहाल जिन्हें अभी डेवलप किया जा रहा है. प्रोग्रेस को यहां ट्रैक किया जा सकता है समस्या 150812265 है.
स्टिकी हेडर (प्रयोग के तौर पर उपलब्ध)
ग्रुप किए गए डेटा की सूचियां दिखाते समय 'स्टिकी हेडर' पैटर्न मददगार होता है. नीचे 'संपर्क सूची' का एक उदाहरण दिया गया है, जिसे हर संपर्क की संपर्क सूची के हिसाब से ग्रुप में बांटा गया है नाम का पहला अक्षर:
LazyColumn
के साथ स्टिकी हेडर पाने के लिए, एक्सपेरिमेंट का इस्तेमाल किया जा सकता है
stickyHeader()
फ़ंक्शन को हेडर सामग्री उपलब्ध कराते हुए:
@OptIn(ExperimentalFoundationApi::class) @Composable fun ListWithHeader(items: List<Item>) { LazyColumn { stickyHeader { Header() } items(items) { item -> ItemRow(item) } } }
ऊपर दिए गए 'संपर्क सूची' उदाहरण जैसे कई हेडर वाली सूची पाने के लिए, ये काम किए जा सकते हैं:
// This ideally would be done in the ViewModel val grouped = contacts.groupBy { it.firstName[0] } @OptIn(ExperimentalFoundationApi::class) @Composable fun ContactsList(grouped: Map<Char, List<Contact>>) { LazyColumn { grouped.forEach { (initial, contactsForInitial) -> stickyHeader { CharacterHeader(initial) } items(contactsForInitial) { contact -> ContactListItem(contact) } } } }
स्क्रोल करने की जगह बदलने के लिए प्रतिक्रिया दिख रही है
कई ऐप्लिकेशन को स्क्रोल करने की जगह और आइटम के लेआउट में हुए बदलावों पर प्रतिक्रिया देनी होती है और सुनना होता है.
लेज़ी कॉम्पोनेंट, शिपिंग के लिए इस्तेमाल किए जाने वाले मुख्य कॉम्पोनेंट को,
LazyListState
:
@Composable fun MessageList(messages: List<Message>) { // Remember our own LazyListState val listState = rememberLazyListState() // Provide it to LazyColumn LazyColumn(state = listState) { // ... } }
आसान इस्तेमाल के मामलों में, ऐप्लिकेशन को आम तौर पर सिर्फ़
दिखाई देने वाला पहला आइटम. इसके लिए
LazyListState
यह
firstVisibleItemIndex
और
firstVisibleItemScrollOffset
प्रॉपर्टी.
अगर हम किसी बटन को दिखाने या छिपाने के उदाहरण का इस्तेमाल इस आधार पर करें कि उपयोगकर्ता ने पहले आइटम को स्क्रोल किया है या नहीं, तो:
@OptIn(ExperimentalAnimationApi::class) @Composable fun MessageList(messages: List<Message>) { Box { val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } // Show the button if the first visible item is past // the first item. We use a remembered derived state to // minimize unnecessary compositions val showButton by remember { derivedStateOf { listState.firstVisibleItemIndex > 0 } } AnimatedVisibility(visible = showButton) { ScrollToTopButton() } } }
कंपोज़िशन में स्थिति को सीधे तौर पर पढ़ना तब फ़ायदेमंद होता है, जब आपको अपडेट करना हो
अन्य यूज़र इंटरफ़ेस (यूआई) कंपोज़ेबल. हालांकि, कुछ मामलों में ऐसे भी उदाहरण हो सकते हैं जहां इवेंट की ज़रूरत न हो
करने के लिए इस्तेमाल किया जा सकता है. इसका एक सामान्य उदाहरण यह है कि
जब उपयोगकर्ता किसी खास पॉइंट से स्क्रोल कर लेता है, तब Analytics इवेंट. मैनेज करने के लिए
साथ ही, हम किसी
snapshotFlow()
:
val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex } .map { index -> index > 0 } .distinctUntilChanged() .filter { it } .collect { MyAnalyticsService.sendScrolledPastFirstItemEvent() } }
LazyListState
उन सभी आइटम के बारे में भी जानकारी देता है जो फ़िलहाल
दिखाई जा रही है और उनकी सीमाएँ दिखाई जा सकती हैं,
layoutInfo
प्रॉपर्टी. ज़्यादा जानकारी के लिए,
LazyListLayoutInfo
क्लास में शामिल हों.
स्क्रोल करने की जगह को कंट्रोल करना
स्क्रोल पोज़िशन पर प्रतिक्रिया देने के साथ-साथ, यह ऐप्लिकेशन इन कामों में
और स्क्रोल की पोज़िशन भी कंट्रोल करें.
LazyListState
scrollToItem()
के ज़रिए इसकी सुविधा देता है
फ़ंक्शन, जो ‘तुरंत’
स्क्रोल की पोज़िशन और animateScrollToItem()
जो ऐनिमेशन का इस्तेमाल करके स्क्रोल करते हैं (स्मूद स्क्रोल भी कहा जाता है):
@Composable fun MessageList(messages: List<Message>) { val listState = rememberLazyListState() // Remember a CoroutineScope to be able to launch val coroutineScope = rememberCoroutineScope() LazyColumn(state = listState) { // ... } ScrollToTopButton( onClick = { coroutineScope.launch { // Animate scroll to the first item listState.animateScrollToItem(index = 0) } } ) }
बड़े डेटा-सेट (पेजिंग)
पेजिंग लाइब्रेरी की मदद से, ऐप्लिकेशन ये काम कर सकते हैं
आइटम की बड़ी सूची का इस्तेमाल करने, सूची के छोटे-छोटे हिस्सों को लोड करने और दिखाने की सुविधा
ज़रूरी है. पेजिंग 3.0 और उसके बाद के वर्शन में
androidx.paging:paging-compose
लाइब्रेरी.
पेज वाले कॉन्टेंट की सूची दिखाने के लिए, हम
collectAsLazyPagingItems()
एक्सटेंशन फ़ंक्शन का इस्तेमाल करता है और फिर लौटाए गए
LazyPagingItems
हमारे LazyColumn
में items()
तक. व्यू में पेजिंग सहायता की तरह ही,
डेटा लोड होने के दौरान प्लेसहोल्डर दिखाएं. इसके लिए, यह देखें कि item
, null
है या नहीं:
@Composable fun MessageList(pager: Pager<Int, Message>) { val lazyPagingItems = pager.flow.collectAsLazyPagingItems() LazyColumn { items( lazyPagingItems.itemCount, key = lazyPagingItems.itemKey { it.id } ) { index -> val message = lazyPagingItems[index] if (message != null) { MessageRow(message) } else { MessagePlaceholder() } } } }
लेज़ी लेआउट का इस्तेमाल करने से जुड़ी सलाह
अगर आपको यह पक्का करना है कि आपके लेज़ी लेआउट सही तरीके से काम करें, तो ये सुझाव दिए गए हैं.
0 पिक्सल वाले आइटम का इस्तेमाल करने से बचें
ऐसा उन स्थितियों में हो सकता है, जहां उदाहरण के लिए, आपको एसिंक्रोनस रूप से बाद में अपनी सूची के आइटम को भरने के लिए, इमेज जैसा कुछ डेटा वापस पाएं. इससे लेज़ी लेआउट अपने सभी आइटम पहले में लिख देगा की लंबाई 0 पिक्सल है और यह डाइमेंशन कॉलम में व्यूपोर्ट. आइटम लोड होने और उनकी ऊंचाई बढ़ जाने के बाद, लेज़ी लेआउट फिर उन सभी आइटम को खारिज कर दिया जाएगा जिन्हें ग़ैर-ज़रूरी तौर पर बनाया गया है ध्यान दें, क्योंकि वे असल में व्यूपोर्ट में फ़िट नहीं हो सकते. इससे बचने के लिए, आपको अपने आइटम के लिए डिफ़ॉल्ट साइज़ सेट करना चाहिए, ताकि लेज़ी लेआउट व्यूपोर्ट में कितने आइटम फ़िट हो सकते हैं, इसका हिसाब लगाने के लिए सही तरीका:
@Composable fun Item(imageUrl: String) { AsyncImage( model = rememberAsyncImagePainter(model = imageUrl), modifier = Modifier.size(30.dp), contentDescription = null // ... ) }
जब आपको पता चलता है कि डेटा होने के बाद आपके आइटम का अनुमानित साइज़ अपने-आप लोड होने की सुविधा का इस्तेमाल करके, यह पक्का किया जा सकता है कि आपके आइटम का साइज़ लोड करने से पहले और बाद में एक जैसा दिखाना. उदाहरण के लिए, कुछ प्लेसहोल्डर जोड़ना. इससे स्क्रोल करने की सही जगह को बनाए रखने में मदद मिलेगी.
एक ही दिशा में स्क्रोल किए जा सकने वाले कॉम्पोनेंट को नेस्ट करने से बचें
यह सिर्फ़ उन मामलों में लागू होता है जहां पहले से तय नियमों के बिना, स्क्रोल किए जा सकने वाले बच्चों को नेस्ट किया जाता है
पैरंट की साइज़ के लिए, जिसे स्क्रोल किया जा सकता है. उदाहरण के लिए,
वर्टिकल तौर पर स्क्रोल करने की सुविधा में, तय ऊंचाई के बिना चाइल्ड LazyColumn
को नेस्ट करें
Column
पैरंट:
// throws IllegalStateException Column( modifier = Modifier.verticalScroll(state) ) { LazyColumn { // ... } }
इसके बजाय, सभी कंपोज़ेबल को रैप करने से, यही नतीजा मिल सकता है
में एक पैरंट LazyColumn
और इसके DSL का इस्तेमाल करके अलग-अलग तरह के
कॉन्टेंट. इसकी मदद से, एक आइटम के साथ-साथ, कई सूची आइटम बाहर रखे जा सकते हैं,
एक ही जगह पर देखें:
LazyColumn { item { Header() } items(data) { item -> PhotoItem(item) } item { Footer() } }
ध्यान रखें कि वे मामले जब अलग-अलग दिशा वाले लेआउट नेस्ट किए जाते हैं,
उदाहरण के लिए, स्क्रोल किए जा सकने वाले पैरंट Row
और चाइल्ड LazyColumn
को अनुमति दी जाती है:
Row( modifier = Modifier.horizontalScroll(scrollState) ) { LazyColumn { // ... } }
ऐसे मामले जहां आप अब भी समान दिशा वाले लेआउट का इस्तेमाल करते हैं, लेकिन नेस्ट किए गए चिल्ड्रेन के लिए एक तय साइज़:
Column( modifier = Modifier.verticalScroll(scrollState) ) { LazyColumn( modifier = Modifier.height(200.dp) ) { // ... } }
एक ही आइटम में कई एलिमेंट को शामिल करने से बचें
इस उदाहरण में, दूसरा आइटम lambda एक ब्लॉक में दो आइटम का उत्सर्जन करता है:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Item(2) } item { Item(3) } // ... }
लेज़ी लेआउट इसे उम्मीद के मुताबिक हैंडल करेंगे - ये पहले एलिमेंट को लेआउट करेंगे के बाद, मानो वे अलग-अलग आइटम थे. हालांकि, कुछ लोग ऐसे भी हैं समस्याओं को कैसे हल किया जाए.
जब किसी एक आइटम के हिस्से के रूप में एक से ज़्यादा एलिमेंट उत्सर्जित किए जाते हैं, तो उन्हें इस तरह हैंडल किया जाता है
का मतलब है कि अब उन्हें अलग-अलग नहीं बनाया जा सकता. अगर एक
स्क्रीन पर एलीमेंट दिखाई देने लगेगा, फिर उससे संबंधित सभी एलीमेंट
आइटम बनाया और मापा जाना चाहिए. इसका इस्तेमाल करने पर, परफ़ॉर्मेंस पर बुरा असर पड़ सकता है
बहुत ज़्यादा. सभी तत्वों को एक ही आइटम में रखने की स्थिति में,
लेज़ी लेआउट के इस्तेमाल को पूरी तरह से नाकाम कर देता है. क्षमता के अलावा
परफ़ॉर्मेंस की समस्याओं की वजह से, एक आइटम में ज़्यादा एलिमेंट रखने से भी रुकावट पैदा होगी.
scrollToItem()
और के साथ animateScrollToItem()
.
हालांकि, एक आइटम में एक से ज़्यादा एलिमेंट रखने के लिए, इस्तेमाल के मान्य उदाहरण हैं, जैसे कि किसी सूची में डिवाइडर होने चाहिए. आपको डिवाइडर की मदद से स्क्रोलिंग में बदलाव नहीं करना है इंडेक्स करना ज़रूरी है, क्योंकि इन्हें इंडिपेंडेंट एलिमेंट नहीं माना जाना चाहिए. साथ ही, परफ़ॉर्मेंस डिवाइडर छोटे होने की वजह से इस पर कोई असर नहीं पड़ेगा. डिवाइडर को आइटम के दिखने से पहले ही दिखेगा, ताकि वह पिछले हिस्से का हिस्सा हो सके आइटम:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Divider() } item { Item(2) } // ... }
पसंद के मुताबिक सेटिंग चुनें
आम तौर पर, लेज़ी लिस्ट में कई आइटम होते हैं और वे स्क्रोल करने वाला कंटेनर. हालांकि, जब आपकी सूची में कुछ आइटम भरे जाते हैं, तो आपके डिज़ाइन की शर्तों और दिशा-निर्देशों को लागू करने के लिए, दिखाई देती है.
ऐसा करने के लिए, कस्टम वर्टिकल का इस्तेमाल करें
Arrangement
और LazyColumn
को पास कर देता है. नीचे दिए गए उदाहरण में, TopWithFooter
ऑब्जेक्ट को सिर्फ़ arrange
तरीका लागू करने की ज़रूरत है. सबसे पहले, यह
एक के बाद एक आइटम. दूसरा, अगर इस्तेमाल की गई कुल ऊंचाई
व्यूपोर्ट की ऊंचाई, यह फ़ुटर को सबसे नीचे स्थान देगा:
object TopWithFooter : Arrangement.Vertical { override fun Density.arrange( totalSize: Int, sizes: IntArray, outPositions: IntArray ) { var y = 0 sizes.forEachIndexed { index, size -> outPositions[index] = y y += size } if (y < totalSize) { val lastIndex = outPositions.lastIndex outPositions[lastIndex] = totalSize - sizes.last() } } }
contentType
जोड़ें
Compose का वर्शन 1.2 लॉन्च किया जा रहा है, ताकि लेज़ी की परफ़ॉर्मेंस को बेहतर बनाया जा सके
लेआउट,
contentType
को भी शामिल किया जा सकता है. इससे आपको यह तय करने में मदद मिलती है कि किस तरह का कॉन्टेंट
लेआउट का आइटम, उन मामलों में जहां आप सूची या ग्रिड बनाते हैं.
आइटम न चुनें:
LazyColumn { items(elements, contentType = { it.type }) { // ... } }
जब आप
contentType
लिखने के लिए सिर्फ़ कंपोज़िशन का इस्तेमाल किया जा सकता है
डालें. दरअसल, ट्रेंडिंग पेज का दोबारा इस्तेमाल करना ज़्यादा कारगर होता है,
मिलते-जुलते स्ट्रक्चर वाले आइटम तैयार करते हैं. साथ ही, कॉन्टेंट के टाइप देना पक्का करता है
लिखें सुविधा, पूरी तरह से A प्रकार के आइटम को लिखने का प्रयास नहीं करती है
B टाइप के अलग-अलग आइटम हैं. इससे कंपोज़िशन के फ़ायदों को बढ़ाने में मदद मिलती है
लेज़ी लेआउट का इस्तेमाल करें.
परफ़ॉर्मेंस को मेज़र करना
लेज़ी लेआउट की परफ़ॉर्मेंस का आकलन सिर्फ़ तब किया जा सकता है, जब और R8 ऑप्टिमाइज़ेशन चालू होना चाहिए. डीबग बिल्ड पर, लेज़ी लेआउट स्क्रोल करने में समय लग सकता है. इस बारे में ज़्यादा जानकारी के लिए, इसे पढ़ें परफ़ॉर्मेंस लिखें.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
RecyclerView
को लेज़ी लिस्ट पर माइग्रेट करें- Compose में यूज़र इंटरफ़ेस (यूआई) की स्थिति सेव करना
- Jetpack Compose के लिए Kotlin