Birçok uygulamanın öğe koleksiyonlarını görüntülemesi gerekir. Bu dokümanda, bunu Jetpack Compose'da verimli bir şekilde nasıl yapabileceğiniz açıklanmaktadır.
Kullanım alanınızın kaydırma gerektirmediğini biliyorsanız basit bir Column
veya Row
(yöne bağlı olarak) kullanabilir ve aşağıdaki gibi bir listede yineleme yaparak her öğenin içeriğini yayınlayabilirsiniz:
@Composable fun MessageList(messages: List<Message>) { Column { messages.forEach { message -> MessageRow(message) } } }
verticalScroll()
değiştiricisini kullanarak Column
öğesini kaydırılabilir hale getirebiliriz.
Daha fazla bilgi için Hareketler
dokümanları bölümüne bakın.
Tembel listeler
Çok sayıda öğe (veya bilinmeyen uzunlukta bir liste) görüntülemeniz gerekiyorsa tüm öğeler görünür durumda olsa da oluşturulduğundan ve yerleştirileceğinden Column
gibi bir düzen kullanmak performans sorunlarına neden olabilir.
Oluştur, yalnızca bileşenin görüntü alanında görünen öğeleri oluşturan ve düzenleyen
bir bileşen grubu sağlar. Bu bileşenler şunlardır: LazyColumn
ve LazyRow
.
Addan da anlaşılacağı gibi LazyColumn
ile LazyRow
arasındaki fark, öğelerin yerleştirildiği ve kaydırıldığı yöndür. LazyColumn
dikey olarak kayan bir liste, LazyRow
ise yatay olarak kayan bir liste oluşturur.
Tembel bileşenler, Oluşturma'daki çoğu düzenden farklıdır. Lazy bileşenleri, @Composable
içerik engelleme parametresini kabul ederek uygulamaların doğrudan composable'lar yaymasına izin vermek yerine bir LazyListScope.()
bloğu sağlar. Bu LazyListScope
bloğu, uygulamaların öğe içeriğini açıklamasına olanak tanıyan bir DSL sunar. Ardından, Tembel bileşen her bir öğenin içeriğini düzen ve kaydırma konumunun gerektirdiği şekilde eklemekten sorumludur.
LazyListScope
DSL
LazyListScope
DSL'si, düzendeki öğeleri açıklamak için çeşitli işlevler sağlar. En temelde, item()
tek bir öğe ve items(Int)
birden çok öğe ekler:
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
gibi öğe koleksiyonlarını eklemenize olanak tanıyan çeşitli uzantı işlevleri de vardır. Bu uzantılar, yukarıdaki Column
örneğimizi kolayca taşımamıza olanak tanır:
/** * import androidx.compose.foundation.lazy.items */ LazyColumn { items(messages) { message -> MessageRow(message) } }
Ayrıca, items()
uzantı işlevinin, dizini sağlayan itemsIndexed()
adlı bir varyantı da vardır. Daha fazla bilgi için lütfen LazyListScope
referansını inceleyin.
Tembel ızgaralar
LazyVerticalGrid
ve LazyHorizontalGrid
composable'ları, öğeleri ızgarada görüntülemeyi destekler. Tembel dikey ızgara, öğelerini birden çok sütuna yayılmış dikey olarak kaydırılabilir bir kapsayıcıda gösterir. Tembel yatay ızgaralar ise yatay eksende aynı davranışa sahip olur.
Izgaralar, listelerle aynı güçlü API özelliklerine sahiptir ve içeriği tanımlamak için çok benzer bir DSL (LazyGridScope.()
) kullanır.
LazyHorizontalGrid
içindeki LazyVerticalGrid
ve rows
parametresi, hücrelerin sütun veya satır şeklinde nasıl oluşturulduğunu kontrol eder.columns
Aşağıdaki örnekte, her bir sütunu en az 128.dp
genişliğinde olacak şekilde ayarlamak için GridCells.Adaptive
kullanılarak öğeler bir ızgara üzerinde gösterilmektedir:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(photos) { photo -> PhotoItem(photo) } }
LazyVerticalGrid
, öğeler için genişlik belirtmenize olanak tanır. Sonrasında ızgara, mümkün olduğunca çok sütuna sığar. Sütun sayısı hesaplandıktan sonra, kalan genişlik sütunlar arasında eşit olarak dağıtılır.
Bu uyarlanabilir boyutlandırma yöntemi, özellikle öğe gruplarını farklı ekran boyutlarında görüntülemek için yararlıdır.
Kullanılacak sütunların sayısını tam olarak biliyorsanız gerekli sütun sayısını içeren GridCells.Fixed
örneğini sağlayabilirsiniz.
Tasarımınız yalnızca belirli öğelerin standart dışı boyutlara sahip olmasını gerektiriyorsa, öğelere özel sütun aralıkları sağlamak için ızgara desteğini kullanabilirsiniz.
LazyGridScope DSL
item
ve items
yöntemlerinin span
parametresiyle sütun kapsamını belirtin.
Aralık kapsamının değerlerinden biri olan maxLineSpan
, uyarlanabilir boyutlandırma kullanılırken sütun sayısı sabit olmadığı için özellikle kullanışlıdır.
Bu örnekte, tam bir satır aralığının nasıl sağlanacağı gösterilmektedir:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 30.dp) ) { item(span = { // LazyGridItemSpanScope: // maxLineSpan GridItemSpan(maxLineSpan) }) { CategoryCard("Fruits") } // ... }
Tembel tablo
LazyVerticalStaggeredGrid
ve LazyHorizontalStaggeredGrid
geç yüklenen ve kademeli bir öğe ızgarası oluşturmanıza olanak tanıyan composable'lardır.
Tembel dikey kademeli ızgara, öğelerini birden çok sütuna yayılan ve bağımsız öğelerin farklı yüksekliklerde olmasına olanak tanıyan dikey olarak kaydırılabilir bir kapsayıcıda görüntüler. Tembel yatay ızgaralar, farklı genişliklere sahip öğelerle yatay eksende aynı davranışa sahiptir.
Aşağıdaki snippet, öğe başına 200.dp
genişlikle LazyVerticalStaggeredGrid
kullanımına ilişkin temel bir örnektir:
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() )
Sabit bir sütun sayısı ayarlamak için StaggeredGridCells.Adaptive
yerine StaggeredGridCells.Fixed(columns)
sütununu kullanabilirsiniz.
Bu işlem, kullanılabilir genişliği sütun (veya yatay ızgarada satır) sayısına böler ve her öğenin belirtilen genişliği (yatay ızgarada bu yüksekliği) kullanmasını sağlar:
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() )
İçerik dolgusu
Bazen içeriğin kenarlarına dolgu eklemeniz gerekir. Geç bileşenler, bunu desteklemek için contentPadding
parametresine bazı PaddingValues
değerleri iletmenizi sağlar:
LazyColumn( contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), ) { // ... }
Bu örnekte, yatay kenarlara (sol ve sağ) 16.dp
, ardından içeriğin üst ve alt kısmına 8.dp
dolgu ekliyoruz.
Bu dolgunun LazyColumn
'nin kendisine değil, içeriğe uygulandığını lütfen unutmayın. Yukarıdaki örnekte, ilk öğe üst kısmına 8.dp
dolgu ekler, son öğe en altına 8.dp
ekler ve tüm öğelerin sol ve sağ tarafında 16.dp
dolgu bulunur.
İçerik aralığı
Öğeler arasına boşluk eklemek için Arrangement.spacedBy()
kullanabilirsiniz.
Aşağıdaki örnekte her bir öğenin arasına 4.dp
boşluk eklenir:
LazyColumn( verticalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
LazyRow
için de benzer durum:
LazyRow( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Öte yandan, ızgaralar hem dikey hem de yatay düzenlemeleri kabul eder:
LazyVerticalGrid( columns = GridCells.Fixed(2), verticalArrangement = Arrangement.spacedBy(16.dp), horizontalArrangement = Arrangement.spacedBy(16.dp) ) { items(photos) { item -> PhotoItem(item) } }
Öğe anahtarları
Varsayılan olarak her öğenin durumu, öğenin listedeki veya ızgaradaki konumuna göre anahtarlanır. Ancak konumu değişen öğeler hatırlanan durumları etkin bir şekilde kaybettiği için bu durum, veri kümesi değişirse sorunlara yol açabilir. LazyColumn
içinde LazyRow
senaryosunu hayal ederseniz, satır öğenin konumu değişirse kullanıcı satır içindeki kaydırma konumunu kaybeder.
Bununla mücadele etmek amacıyla, her öğe için sabit ve benzersiz bir anahtar sağlayıp key
parametresine bir engelleme sağlayabilirsiniz. Sabit anahtar sağlamak, öğe durumunun veri kümesi değişikliklerinde tutarlı olmasını sağlar:
LazyColumn { items( items = messages, key = { message -> // Return a stable + unique key for the item message.id } ) { message -> MessageRow(message) } }
Anahtarları sağlayarak Compose'un yeniden sıralamaları doğru şekilde işlemesine yardımcı olursunuz. Örneğin, öğeniz hatırlandı durumu içeriyorsa ayar tuşları, Oluşturma'nın konumu değiştiğinde bu durumu öğeyle birlikte taşımasına olanak tanır.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = remember { Random.nextInt() } } }
Bununla birlikte, öğe anahtarı olarak kullanabileceğiniz türlerle ilgili bir sınırlama vardır.
Anahtarın türü, Android'in Etkinlik yeniden oluşturulduğunda durumu saklama mekanizması Bundle
tarafından desteklenmelidir. Bundle
; temel öğeler, numaralandırmalar veya
parsel maddeler gibi türleri destekler.
LazyColumn { items(books, key = { // primitives, enums, Parcelable, etc. }) { // ... } }
Etkinlik yeniden oluşturulduğunda veya hatta görünümü bu öğeden uzaklaştırıp geri kaydırdığınızda composable içindeki rememberSaveable
öğesinin geri yüklenebilmesi için anahtarın Bundle
tarafından desteklenmesi gerekir.
LazyColumn { items(books, key = { it.id }) { val rememberedValue = rememberSaveable { Random.nextInt() } } }
Öğe animasyonları
RecyclerView widget'ını kullandıysanız bu widget'ın öğe değişikliklerini otomatik olarak canlandırdığını bilirsiniz.
Geç düzenler, öğelerin yeniden sıralanması için aynı işlevi sağlar.
API oldukça basittir. Tek yapmanız gereken öğe içeriğinde animateItemPlacement
değiştiricisini ayarlamaktır:
LazyColumn { items(books, key = { it.id }) { Row(Modifier.animateItemPlacement()) { // ... } } }
Aşağıdakileri yapmanız gerekirse özel animasyon spesifikasyonu bile sağlayabilirsiniz:
LazyColumn { items(books, key = { it.id }) { Row( Modifier.animateItemPlacement( tween(durationMillis = 250) ) ) { // ... } } }
Taşınan öğenin yeni konumunu bulabilmek için öğelerinizin anahtarlarını sağladığınızdan emin olun.
Yeniden sıralama işlemlerinin yanı sıra, ekleme ve kaldırma işlemleri için öğe animasyonları şu anda geliştirme aşamasındadır. İlerleme durumunu 150812265 numaralı sorundan takip edebilirsiniz.
Yapışkan başlıklar (deneysel)
"Yapışkan başlık" kalıbı, gruplandırılmış verilerin listelerini görüntülerken faydalıdır. Aşağıda, her kişinin baş harfine göre gruplandırılmış bir "kişi listesi" örneği görebilirsiniz:
LazyColumn
ile sabit bir üstbilgi elde etmek için, üstbilgi içeriğini sağlayan deneysel stickyHeader()
işlevini kullanabilirsiniz:
@OptIn(ExperimentalFoundationApi::class) @Composable fun ListWithHeader(items: List<Item>) { LazyColumn { stickyHeader { Header() } items(items) { item -> ItemRow(item) } } }
Yukarıdaki "kişi listesi" örneğinde olduğu gibi birden çok üstbilgiye sahip bir liste oluşturmak için aşağıdakileri yapabilirsiniz:
// 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) } } } }
Kaydırma konumuna tepki verme
Birçok uygulamanın kaydırma konumuna ve öğe düzeni değişikliklerine tepki vermesi ve bunları dinlemesi gerekir.
Lazy (Tembel) bileşenleri, LazyListState
'ı kaldırarak bu kullanım alanını destekler:
@Composable fun MessageList(messages: List<Message>) { // Remember our own LazyListState val listState = rememberLazyListState() // Provide it to LazyColumn LazyColumn(state = listState) { // ... } }
Basit kullanım alanlarında, uygulamaların genellikle yalnızca ilk görünür öğeyle ilgili bilgi sahibi olması gerekir. Bunun için LazyListState
, firstVisibleItemIndex
ve firstVisibleItemScrollOffset
özelliklerini sağlar.
Kullanıcının ilk öğeyi geçip geçmediğine bağlı olarak bir düğme gösterme ve gizleme örneğini kullanırsak:
@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() } } }
Durumu doğrudan bileşimde okumak, kullanıcı arayüzü diğer composable'larını güncellemeniz gerektiğinde faydalıdır ancak etkinliğin aynı bileşim içinde işlenmesinin gerekmediği senaryolar da vardır. Bunun yaygın bir örneği, kullanıcı ekranı kaydırarak belirli bir noktayı geçtikten sonra bir analiz etkinliği göndermektir. Bunu verimli bir şekilde yönetmek için snapshotFlow()
kullanabiliriz:
val listState = rememberLazyListState() LazyColumn(state = listState) { // ... } LaunchedEffect(listState) { snapshotFlow { listState.firstVisibleItemIndex } .map { index -> index > 0 } .distinctUntilChanged() .filter { it } .collect { MyAnalyticsService.sendScrolledPastFirstItemEvent() } }
LazyListState
, görüntülenmekte olan tüm öğeler ve ekrandaki sınırları hakkında da layoutInfo
özelliği aracılığıyla bilgi sağlar. Daha fazla bilgi için LazyListLayoutInfo
sınıfına göz atın.
Kaydırma konumunu kontrol etme
Kaydırma konumuna tepki vermenin yanı sıra, uygulamaların kaydırma konumunu kontrol edebilmesi de yararlı olur.
LazyListState
bunu, kaydırma konumunu "hemen" tutturan ve bir animasyon (yumuşak kaydırma olarak da bilinir) kullanarak kaydıran animateScrollToItem()
işleviyle scrollToItem()
işleviyle destekler:
@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) } } ) }
Büyük veri kümeleri (sayfalama)
Çağrı kitaplığı, uygulamaların büyük öğe listelerini destekleyerek listenin küçük bölümlerini gerektiği şekilde yüklemesini ve görüntülemesini sağlar. 3.0 ve sonraki sürümler, androidx.paging:paging-compose
kitaplığı üzerinden Oluşturma desteği sağlar.
Sayfalı içeriğin listesini görüntülemek için collectAsLazyPagingItems()
uzantı işlevini kullanabilir ve ardından döndürülen LazyPagingItems
öğesini LazyColumn
öğemizde items()
öğesine geçirebiliriz. Görünümlerdeki Sayfalama desteğine benzer şekilde, item
öğesinin null
olup olmadığını kontrol ederek veri yüklenirken yer tutucuları görüntüleyebilirsiniz:
@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() } } } }
Geç düzenleri kullanmayla ilgili ipuçları
Geç düzenlerinizin istediğiniz gibi çalışmasını sağlamak için dikkate alabileceğiniz birkaç ipucu vardır.
0 piksel boyutunda öğeler kullanmaktan kaçının
Bu durum, örneğin sonraki bir aşamada listenizdeki öğeleri doldurmak için eşzamansız olarak bazı veriler (ör. resimler) almayı beklediğiniz senaryolarda gerçekleşebilir. Bu, Lazy düzeninin, yükseklikleri 0 piksel olduğu ve tüm öğeleri görüntü alanına sığabileceği için ilk ölçümde tüm öğelerini oluşturmasına neden olur. Öğeler yüklendikten ve yükseklikleri genişletildikten sonra, Tembel düzenler görüntü alanına tam olarak sığamayacağı için ilk kez gereksiz şekilde oluşturulan diğer tüm öğeleri siler. Bunu önlemek için öğelerinize varsayılan boyutlandırmayı ayarlamalısınız. Böylece Geç düzen, görüntü alanına kaç öğenin gerçekten sığabileceğiyle ilgili doğru hesaplamayı yapabilir:
@Composable fun Item(imageUrl: String) { AsyncImage( model = rememberAsyncImagePainter(model = imageUrl), modifier = Modifier.size(30.dp), contentDescription = null // ... ) }
Veriler eşzamansız olarak yüklendikten sonra öğelerinizin yaklaşık boyutunu biliyorsanız, bazı yer tutucular ekleyerek öğelerinizin boyutunun yüklenmeden önce ve sonra aynı kalmasını sağlamak iyi bir uygulamadır. Bu, doğru kaydırma konumunun korunmasına yardımcı olur.
Aynı yönde kaydırılabilen bileşenleri iç içe yerleştirmekten kaçının
Bu durum yalnızca, önceden tanımlanmış bir boyutu olmayan, aynı yönde başka bir kaydırılabilir üst öğenin içine yerleştirilen kaydırılabilir alt öğelerin iç içe yerleştirildiği durumlar için geçerlidir. Örneğin, sabit yüksekliği olmayan bir alt LazyColumn
öğesini, dikey olarak kaydırılabilir bir Column
üst öğesi içine yerleştirmeye çalışıldığında:
// throws IllegalStateException Column( modifier = Modifier.verticalScroll(state) ) { LazyColumn { // ... } }
Bunun yerine, tüm composable'larınızı bir üst LazyColumn
içine sarmalayarak ve farklı içerik türlerini geçirmek için DSL'sini kullanarak aynı sonucu elde edebilirsiniz. Bu, tek bir yerde tek öğelerin yanı sıra birden çok liste öğesinin de yayınlanmasını sağlar:
LazyColumn { item { Header() } items(data) { item -> PhotoItem(item) } item { Footer() } }
Farklı yön düzenlerini iç içe yerleştirdiğiniz durumlarda (ör. kaydırılabilir üst öğe Row
ve alt LazyColumn
) izin verildiğini unutmayın:
Row( modifier = Modifier.horizontalScroll(scrollState) ) { LazyColumn { // ... } }
Aynı yön düzenlerini kullanmaya devam ettiğiniz ancak iç içe yerleştirilmiş alt öğeler için sabit bir boyut ayarladığınız durumlarda:
Column( modifier = Modifier.verticalScroll(scrollState) ) { LazyColumn( modifier = Modifier.height(200.dp) ) { // ... } }
Tek bir öğeye birden çok öğe koymaya dikkat edin
Bu örnekte, lambda ikinci öğesi bir blokta 2 öğe yayınlar:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Item(2) } item { Item(3) } // ... }
Tembel düzenler bunu beklendiği gibi ele alır. Öğeleri, farklı öğelermiş gibi birbiri ardına düzenlerler. Ancak, bunu yaparken bazı sorunlar var.
Bir öğenin parçası olarak birden fazla öğe yayınlandığında bunlar tek bir varlık olarak işlenir. Diğer bir deyişle artık ayrı ayrı oluşturulamazlar. Ekranda bir öğe görünür hale gelirse öğeye karşılık gelen tüm öğelerin oluşturulması ve ölçülmesi gerekir. Bu, aşırı kullanılırsa performansta düşüşe neden olabilir. Tüm öğelerin tek bir öğeye yerleştirilmesi aşırı örnekte, Geç düzenleri kullanma amacına tamamen engel olur. Potansiyel performans sorunlarının yanı sıra, bir öğeye daha fazla öğe yerleştirmek de scrollToItem()
ve animateScrollToItem()
öğelerini etkiler.
Ancak bir öğeye birden çok öğe yerleştirmek için, bir listenin içinde ayırıcılar bulunması gibi geçerli kullanım alanları vardır. Ayrı öğeler olarak görülmemeleri gerektiğinden, ayırıcıların kaydırma dizinlerini değiştirmesini istemezsiniz. Ayrıca, ayırıcılar küçük olduğundan performans etkilenmez. Öğe görünür hale gelmeden önce bir ayırıcının görünür olması gerekir. Böylece bunlar önceki öğenin parçası olabilir:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Divider() } item { Item(2) } // ... }
Özel düzenlemeler kullanmayı düşünün
Tembel listeler genellikle çok sayıda öğeye sahiptir ve bunlar, kaydırma kapsayıcısının boyutundan daha fazla yer kaplarlar. Bununla birlikte, listeniz birkaç öğeyle doldurulduğunda tasarımınız, bunların görüntü alanında nasıl konumlandırılacağıyla ilgili daha spesifik gereksinimlere sahip olabilir.
Bunu başarmak için özel sektörü Arrangement
kullanabilir ve LazyColumn
ürününe iletebilirsiniz. Aşağıdaki örnekte, TopWithFooter
nesnesinin yalnızca arrange
yöntemini uygulaması gerekir. İlk olarak, öğeleri
birbiri ardına yerleştirir. İkinci olarak, kullanılan toplam yükseklik görüntü alanı yüksekliğinden düşükse altbilgi en alta yerleştirilir:
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
eklemeyi düşünün
Compose 1.2'den başlayarak tembel düzeninizin performansını en üst düzeye çıkarmak için listelerinize veya ızgaralarınıza contentType
eklemeniz önerilir. Bu, birden fazla farklı türde öğe içeren bir liste veya ızgara oluşturduğunuz durumlarda, düzenin her bir öğesi için içerik türünü belirtmenize olanak tanır:
LazyColumn { items(elements, contentType = { it.type }) { // ... } }
contentType
özelliğini sağladığınızda Composer, besteleri yalnızca aynı türdeki öğeler arasında yeniden kullanabilir. Benzer yapıya sahip öğeleri oluşturduğunuzda yeniden kullanmak daha verimli olduğundan, içerik türlerinin sağlanması, Oluştur'un tamamen farklı bir B türü öğenin üzerine A türünde bir öğe oluşturmaya çalışmamasını sağlar. Bu, besteyi yeniden kullanmanın ve geç düzen performansınızın avantajlarını en üst düzeye çıkarmanıza yardımcı olur.
Performansı ölçme
Geç düzenin performansını yalnızca sürüm modunda çalışırken ve R8 optimizasyonu etkin durumdayken güvenilir şekilde ölçebilirsiniz. Hata ayıklama derlemelerinde Geç düzen kaydırması daha yavaş görünebilir. Bu konu hakkında daha fazla bilgi için Oluşturma performansı bölümünü okuyun.
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken görüntülenir
RecyclerView
öğesini geç listeye taşıyın- Oluşturma penceresinde kullanıcı arayüzü durumunu kaydetme
- Jetpack Compose için Kotlin