Birçok uygulamanın, öğe koleksiyonlarını görüntülemesi gerekir. Bu dokümanda, Jetpack Compose'da bunu nasıl verimli bir şekilde yapabileceğiniz açıklanmaktadır.
Kullanım alanınızda kaydırma gerekmediğini biliyorsanız basit bir Column
veya Row
(yöne bağlı olarak) kullanıp bir liste üzerinde aşağıdaki şekilde iterasyon 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
'u kaydırılabilir hale getirebiliriz.
Tembel listeler
Çok sayıda öğe (veya bilinmeyen uzunluktaki bir liste) göstermeniz gerekiyorsa Column
gibi bir düzen kullanmak performans sorunlarına neden olabilir. Bunun nedeni, tüm öğelerin görünür olup olmadığına bakılmaksızın derlenmesi ve yerleştirilmesidir.
Oluşturma, yalnızca bileşenin görüntü alanında görünen öğeleri oluşturan ve düzenleyen bir bileşen grubu sağlar. LazyColumn
ve LazyRow
bu bileşenler arasındadır.
Adından da anlaşılacağı gibi, LazyColumn
ile LazyRow
arasındaki fark, öğelerin düzenlenme ve kaydırma yönüdür. LazyColumn
dikey kaydırmalı bir liste, LazyRow
ise yatay kaydırmalı bir liste oluşturur.
Yavaş bileşenler, Oluştur'daki çoğu düzenden farklıdır. Tembel bileşenler, @Composable
içerik bloku parametresini kabul ederek uygulamaların doğrudan composable'ları yayımlamasına izin vermek yerine bir LazyListScope.()
bloğu sağlar. Bu LazyListScope
bloku, uygulamaların öğe içeriklerini açıklamasına olanak tanıyan bir DSL sunar. Daha sonra geç bileşeni, düzen ve kaydırma konumunun gerektirdiği şekilde her bir öğenin içeriğini eklemekten sorumludur.
LazyListScope
DSL
LazyListScope
DSL'si, düzendeki öğeleri tanımlamak için çeşitli işlevler sağlar. En basit haliyle, item()
tek bir öğe, items(Int)
ise birden fazla öğ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ı 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) } }
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, öğelerin ızgarada gösterilmesini destekler. Yavaş dikey ızgaralar öğelerini birden fazla sütuna yayılmış, dikey olarak kaydırılabilir bir kapsayıcıda gösterir. Yavaş yatay ızgaralar ise yatay eksende aynı davranışı gösterir.
Izgaralar, listelerle aynı güçlü API özelliklerine sahiptir ve ayrıca içeriği tanımlamak için çok benzer bir DSL (LazyGridScope.()
) kullanır.
LazyVerticalGrid
içindeki columns
parametresi ve LazyHorizontalGrid
içindeki rows
parametresi, hücrelerin sütun veya satır halinde nasıl oluşturulacağını kontrol eder. Aşağıdaki örnekte, her sütunu en az 128.dp
genişliğinde ayarlamak için GridCells.Adaptive
kullanılarak öğeler ızgara şeklinde gösterilmektedir:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 128.dp) ) { items(photos) { photo -> PhotoItem(photo) } }
LazyVerticalGrid
, öğeler için bir genişlik belirtmenize olanak tanır. Ardından ızgara, mümkün olduğunca çok sütuna sığdırılır. Kalan genişlik, sütun sayısı hesaplandıktan sonra sütunlar arasında eşit olarak dağıtılır.
Bu uyarlanabilir boyutlandırma yöntemi, özellikle farklı ekran boyutlarında öğe grupları görüntülemek için yararlıdır.
Kullanılacak sütun sayısını tam olarak biliyorsanız bunun yerine, GridCells.Fixed
için gerekli sayıda sütun içeren bir örnek sağlayabilirsiniz.
Tasarımınız yalnızca belirli öğelerin standart olmayan boyutlara sahip olmasını gerektiriyorsa öğeler için özel sütun aralıkları sağlamak üzere ızgara desteğini kullanabilirsiniz.
Sütun kapsamını, LazyGridScope DSL
item
ve items
yöntemlerinin span
parametresiyle belirtin.
Aralık kapsamının değerlerinden biri olan maxLineSpan
, sütun sayısı sabit olmadığı için özellikle uyarlanabilir boyutlandırma kullandığınızda yararlı olur.
Bu örnekte, tam satır kapsamının nasıl sağlanacağı gösterilmektedir:
LazyVerticalGrid( columns = GridCells.Adaptive(minSize = 30.dp) ) { item(span = { // LazyGridItemSpanScope: // maxLineSpan GridItemSpan(maxLineSpan) }) { CategoryCard("Fruits") } // ... }
Tembel ızgara
LazyVerticalStaggeredGrid
ve LazyHorizontalStaggeredGrid
, geç yüklenen, aşamalı bir öğe ızgarası oluşturmanızı sağlayan composable'lardır.
Yavaş dikey kademeli ızgara, öğelerini birden fazla sütuna yayılan ve öğelerin farklı yüksekliklere sahip olmasına olanak tanıyan dikey olarak kaydırılabilir bir kapsayıcıda gösterir. Tembel yatay ızgaralar, farklı genişliklere sahip öğelerle yatay eksende aynı davranışa sahiptir.
Aşağıdaki snippet, öğe başına 200.dp
genişliğinde LazyVerticalStaggeredGrid
kullanımına dair 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 sayıda sütun ayarlamak için StaggeredGridCells.Adaptive
yerine StaggeredGridCells.Fixed(columns)
değerini kullanabilirsiniz.
Bu işlem, mevcut genişliği sütun sayısına (veya yatay ızgara için satır sayısına) böler ve her öğenin bu genişliği (veya yatay ızgara için yüksekliği) kaplaması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. Yavaş bileşenler, bunu desteklemek için contentPadding
parametresine bazı PaddingValues
iletmenize olanak tanır:
LazyColumn( contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp), ) { // ... }
Bu örnekte, yatay kenarlara (sol ve sağ) 16.dp
dolgu, ardından içeriğin üst ve alt kısmına 8.dp
dolgu ekliyoruz.
Bu dolgunun LazyColumn
öğesine değil, içeriğin kendisine uygulandığını lütfen unutmayın. Yukarıdaki örnekte, ilk öğe üst kısmına 8.dp
dolgu, son öğe alt kısmına 8.dp
dolgu, tüm öğeler ise sol ve sağ tarafına 16.dp
dolgu ekler.
İçerik aralığı
Öğeler arasında boşluk eklemek için Arrangement.spacedBy()
işlevini kullanabilirsiniz.
Aşağıdaki örnekte her öğe arasına 4.dp
boşluk eklenmiştir:
LazyColumn( verticalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Benzer şekilde LazyRow
için:
LazyRow( horizontalArrangement = Arrangement.spacedBy(4.dp), ) { // ... }
Bununla birlikte ı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 tablodaki konumuna göre anahtarlanır. Bununla birlikte, konumu değişen öğeler hatırlanan durumları etkili bir şekilde kaybedeceği için bu durum, veri kümesi değişirse sorunlara yol açabilir. LazyRow
senaryosunu LazyColumn
içinde göz önünde bulundurursanız satır, öğe konumunu değiştirirse 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ğlayarak key
parametresi için bir blok sağlayabilirsiniz. Sabit bir 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 anahtarları ayarlamak, Oluştur'un 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 sahip olduğu durumları koruma mekanizması olan Bundle
tarafından desteklenmelidir. Bundle
, ilkel, enum veya Parcelables gibi türleri destekler.
LazyColumn { items(books, key = { // primitives, enums, Parcelable, etc. }) { // ... } }
composable'ın içindeki rememberSaveable
öğesinin, Etkinlik yeniden oluşturulduğunda, hatta bu öğeden ayrılıp geri kaydırdığınızda bile geri yüklenebilmesi için bu 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 öğe değişikliklerini otomatik olarak animasyonlu hale getirdiğini bilirsiniz.
Yavaş düzenler, öğelerin yeniden sıralanmasında aynı işlevi sağlar.
API basittir. animateItem
değiştiricisini öğe içeriğine ayarlamanız yeterlidir:
LazyColumn { // It is important to provide a key to each item to ensure animateItem() works as expected. items(books, key = { it.id }) { Row(Modifier.animateItem()) { // ... } } }
Şunlara ihtiyacınız varsa özel animasyon spesifikasyonu bile sağlayabilirsiniz:
LazyColumn { items(books, key = { it.id }) { Row( Modifier.animateItem( fadeInSpec = tween(durationMillis = 250), fadeOutSpec = tween(durationMillis = 100), placementSpec = spring(stiffness = Spring.StiffnessLow, dampingRatio = Spring.DampingRatioMediumBouncy) ) ) { // ... } } }
Taşınan öğenin yeni konumunun bulunabilmesi için öğelerinize anahtar sağladığınızdan emin olun.
Yapışkan başlıklar (deneysel)
"Yapışkan başlık" kalıbı, gruplandırılmış verilerin listelerini görüntülerken kullanışlıdır. Aşağıda, her kişinin baş harfine göre gruplandırılmış bir "kişiler listesi" örneğini görebilirsiniz:
LazyColumn
ile yapışkan bir başlık elde etmek için deneme amaçlı stickyHeader()
işlevini kullanarak başlık içeriğini sağlayabilirsiniz:
@OptIn(ExperimentalFoundationApi::class) @Composable fun ListWithHeader(items: List<Item>) { LazyColumn { stickyHeader { Header() } items(items) { item -> ItemRow(item) } } }
Yukarıdaki "kişiler listesi" örneğinde olduğu gibi, birden çok başlık içeren bir liste oluşturmak için şunları 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 konumu ve öğe düzeni değişikliklerine tepki vermesi ve bu değişiklikleri dinlemesi gerekir.
Tembel bileşenler, LazyListState
değerini 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ı için uygulamaların genellikle yalnızca ilk görünür öğeyle ilgili bilgileri bilmesi 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üğmeyi gösterme ve gizleme örneğini kullanırsak:
@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 kompozisyonda okumak, diğer kullanıcı arayüzü composable'larını güncellemeniz gerektiğinde faydalıdır. Ancak etkinliğin aynı bileşimde işlenmesinin gerekmediği senaryolarla da karşılaşılabilir. Bunun yaygın bir örneği, kullanıcı belirli bir noktanın ötesine geçtiğinde bir Analytics etkinliği göndermektir. Bu işlemi verimli bir şekilde gerçekleştirmek 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
, layoutInfo
mülkü aracılığıyla şu anda gösterilen tüm öğeler ve ekrandaki sınırları hakkında da bilgi sağlar. Daha fazla bilgi için LazyListLayoutInfo
sınıfına bakın.
Kaydırma konumunu kontrol etme
Uygulamaların kaydırma konumuna tepki vermesinin yanı sıra kaydırma konumunu kontrol edebilmesi de yararlıdır.
LazyListState
, kaydırma konumunu "hemen" sabitleyen scrollToItem()
işlevi ve animasyon (sürükleyici kaydırma olarak da bilinir) kullanarak kaydıran animateScrollToItem()
işlevi aracılığıyla bunu 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 desteklemesine olanak tanır. Bu sayede, listenin küçük parçalarını yükleyip görüntüleyebilir. 3.0 ve sonraki sürümler, androidx.paging:paging-compose
kitaplığı aracılığıyla Compose desteği sağlar.
Sayfalandırılmış içeriklerin listesini görüntülemek için collectAsLazyPagingItems()
uzantı işlevini kullanıp döndürülen LazyPagingItems
öğesini LazyColumn
içinde items()
öğesine iletebiliriz. Görünümlerdeki Sayfalandırma desteğine benzer şekilde, veriler yüklenirken item
için null
olup olmadığını kontrol ederek 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() } } } }
Yavaş düzenleri kullanmayla ilgili ipuçları
Tembel düzenlerinizin gerektiği gibi çalışmasını sağlamak için göz önünde bulundurabileceğiniz birkaç ipucu vardır.
0 piksel boyutunda öğeler kullanmaktan kaçının
Bu durum, örneğin listenizin öğelerini daha sonraki bir aşamada doldurmak için resimler gibi bazı verileri eşzamansız olarak almanız beklenen senaryolarda ortaya çıkabilir. Bu durumda, öğelerin yüksekliği 0 piksel olduğu ve tüm öğeler görüntü alanına sığabileceği için, tembel düzenin tüm öğelerini ilk ölçümde oluşturmasına neden olur. Öğeler yüklenip yükseklikleri artırıldıktan sonra Tembel düzenler, ilk seferde gereksiz yere oluşturulan diğer tüm öğeleri siler. Çünkü bunlar görüntü alanına sığmaz. Bunu önlemek için öğelerinize varsayılan boyutlandırmayı ayarlamanız gerekir. Böylece, yavaş düzen, görüntü alanına kaç öğenin sığabileceğini doğru şekilde hesaplayabilir:
@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 bildiğinizde, öğelerinizin boyutunun yükleme öncesi ve sonrası aynı kalmasını sağlamak için bazı yer tutucular ekleyerek iyi bir uygulama yapabilirsiniz. Bu sayede, kaydırma konumunu doğru tutabilirsiniz.
Aynı yönde kaydırılabilir bileşenleri iç içe yerleştirmekten kaçının
Bu durum yalnızca, önceden tanımlanmış bir boyut olmadan kaydırılabilir alt öğelerin aynı yönde kaydırılabilir başka bir üst öğe içine yerleştirildiği durumlarda geçerlidir. Örneğin, dikey olarak kaydırılabilir bir Column
üst öğesinin içine sabit yüksekliği olmayan bir alt LazyColumn
alt öğesi yerleştirmeye çalıştığınızda:
// 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 iletmek için DSL'yi kullanarak aynı sonucu elde edebilirsiniz. Bu, tek bir öğenin ve birden çok liste öğesinin tek bir yerde 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 durumlara (örneğin, kaydırılabilir üst 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 belirlediğiniz durumlarda da:
Column( modifier = Modifier.verticalScroll(scrollState) ) { LazyColumn( modifier = Modifier.height(200.dp) ) { // ... } }
Tek bir öğeye birden çok öğe yerleştirmemeye dikkat edin
Bu örnekte, lambda adlı ikinci öğe 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üzenler. Ancak bunu yapmanın birkaç sorunu vardır.
Birden fazla öğe tek bir öğenin parçası olarak yayınlandığında tek bir varlık olarak ele alınır. Bu nedenle, artık tek tek derlenemezler. Ekranda bir öğe görünür hale gelirse bu öğeye karşılık gelen tüm öğelerin oluşturulması ve ölçülmesi gerekir. Bu, aşırı kullanıldığında performansı olumsuz etkileyebilir. Tüm öğeleri tek bir öğeye yerleştirmek aşırı bir örnek olarak, Tembel düzenlerin kullanılmasının amaçlarını tamamen ortadan kaldırır. Olası performans sorunlarının yanı sıra, bir öğeye daha fazla öğe eklemek scrollToItem()
ve animateScrollToItem()
işlevlerini de etkiler.
Bununla birlikte, bir öğeye birden fazla öğe yerleştirmek için (liste içinde ayırıcılar kullanma gibi) geçerli kullanım alanları vardır. Bağımsız öğeler olarak kabul edilmemeleri gerektiğinden, bölücülerin kaydırma dizelerini değiştirmesini istemezsiniz. Ayrıca, bölücüler küçük olduğundan performans etkilenmez. Bölücünün, önceki öğenin parçası olabilmesi için önceki öğe görünür olduğunda görünür olması gerekir:
LazyVerticalGrid( columns = GridCells.Adaptive(100.dp) ) { item { Item(0) } item { Item(1) Divider() } item { Item(2) } // ... }
Özel düzenlemeler kullanmayı düşünün
Genellikle, yavaş listeler çok sayıda öğe içerir ve kaydırılabilir kapsayıcının boyutundan daha fazla yer kaplar. Bununla birlikte, listeniz az sayıda öğeyle doldurulduğunda tasarımınız, bunların görüntü alanına nasıl yerleştirilmesi gerektiğine dair daha spesifik gereksinimlere sahip olabilir.
Bunu yapmak için özel sektörü Arrangement
kullanıp LazyColumn
bölümüne aktarabilirsiniz. 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
ekleyebilirsiniz
Compose 1.2'den başlayarak Lazy düzeninizin performansını en üst düzeye çıkarmak için listelerinize veya ızgaralarınıza contentType
ekleyebilirsiniz. Bu, birden çok farklı öğe türünden oluşan 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
sağladığınızda, Compose yalnızca aynı türdeki öğeler arasında kompozisyonları yeniden kullanabilir. Benzer yapıya sahip öğeler oluşturduğunuzda yeniden kullanma daha verimli olduğundan, içerik türlerini belirtmek, Oluştur'un tamamen farklı bir B türü öğenin üzerine A türü bir öğe oluşturmaya çalışmamasını sağlar. Bu sayede, kompozisyonları yeniden kullanmanın avantajlarını ve yavaş düzen performansınızı en üst düzeye çıkarabilirsiniz.
Performansı ölçme
Lazy düzeninin performansını yalnızca yayın modunda çalışırken ve R8 optimizasyonunu etkinleştirdiğinizde güvenilir şekilde ölçebilirsiniz. Hata ayıklama derlemelerinde, tembel düzen kaydırması daha yavaş görünebilir. Bu hakkında daha fazla bilgi için Performans oluşturma bölümünü okuyun.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
RecyclerView
adlı cihazı geç listeye taşı- Oluştur'da kullanıcı arayüzü durumunu kaydetme
- Jetpack Compose için Kotlin