Listeler ve ızgaralar

Birçok uygulamanın, öğe koleksiyonlarını görüntülemesi gerekir. Bu belgede, projenizi bunu Jetpack Compose'da verimli bir şekilde yapabiliyor.

Kullanım alanınızın herhangi bir kaydırma gerektirmediğini biliyorsanız, basit bir Column veya Row kullanın (yöne bağlı olarak) ve her bir öğenin içeriğini yineleme şu şekilde yapılır:

@Composable
fun MessageList(messages: List<Message>) {
    Column {
        messages.forEach { message ->
            MessageRow(message)
        }
    }
}

verticalScroll() değiştiricisini kullanarak Column öğesini kaydırılabilir hale getirebiliriz.

Tembel listeler

Çok sayıda öğe (veya uzunluğu bilinmeyen bir liste) görüntülemeniz gerekiyorsa Column gibi bir düzen kullanmak, tüm öğeler oluşturulacağı ve görünür olup olmadıklarına göre düzenleneceği için performans sorunlarına neden olabilir.

Oluşturma, yalnızca aşağıdaki durumlardan oluşan öğeleri oluşturan ve düzenleyen bileşenlerin görüntü alanında görünür olması gerekir. Bu bileşenler şunları içerir: LazyColumn ve LazyRow.

Adından da anlaşılacağı gibi LazyColumn ve LazyRow öğelerini yerleştirdikleri ve kaydırdıkları yöndür. LazyColumn dikey olarak kayan bir liste oluşturur, LazyRow ise yatay olarak bir kaydırma listesi.

Tembel bileşenler, Compose'daki çoğu düzenden farklıdır. Şunun yerine: bir @Composable içerik engelleme parametresini kabul ederek, uygulamaların composable'lar yayınlarken, Tembel bileşenler bir LazyListScope.() blok sağlar. Bu LazyListScope blok, uygulamaların öğe içeriğini tanımlamasına olanak tanıyan bir DSL sunar. İlgili içeriği oluşturmak için kullanılan Daha sonra Tembel bileşen, her bir öğenin içeriğini göre değişir.

LazyListScope DSL

LazyListScope DSL'si, öğeleri açıklamak için çeşitli işlevler sağlar tıklayın. En temelde item() tek bir öğe ekler ve items(Int) Kullanıcı birden çok öğe eklediğinde:

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")
    }
}

Çok sayıda uzantıya metin eklememize olanak tanıyan öğe koleksiyonları, List gibi. Bu uzantılar, reklamımızı yukarıdaki Column örneğimizi taşıyın:

/**
 * import androidx.compose.foundation.lazy.items
 */
LazyColumn {
    items(messages) { message ->
        MessageRow(message)
    }
}

Ayrıca, items() uzantı işlevi itemsIndexed(), Böylece dizini sağlar. Daha fazla bilgi için lütfen LazyListScope inceleyebilirsiniz.

Tembel ızgaralar

İlgili içeriği oluşturmak için kullanılan LazyVerticalGrid ve LazyHorizontalGrid composable'lar, öğelerin ızgarada gösterilmesi için destek sağlar. Tembel dikey ızgara öğelerini dikey olarak kaydırılabilen bir kapsayıcıda görüntüler. Tembel yatay ızgaralar ise aynı davranışa sahip olacak, ancak Tembel yatay ızgaralar yatay eksende yer alır.

Izgaralar, listelerle aynı güçlü API özelliklerine sahiptir ve aynı zamanda bir çok benzer DSL LazyGridScope.() tercih edebilirsiniz.

Fotoğraf ızgarasının gösterildiği bir telefonun ekran görüntüsü

Şuradaki columns parametresi: LazyVerticalGrid ve rows parametresini dahil edin: LazyHorizontalGrid hücrelerin sütun veya satırlara nasıl ayrılacağını kontrol edebilirsiniz. Aşağıdakiler örnek, öğeleri bir ızgarada gösteriyor. GridCells.Adaptive değerini her bir sütunu en az 128.dp genişlikte olacak şekilde ayarlamak için:

LazyVerticalGrid(
    columns = GridCells.Adaptive(minSize = 128.dp)
) {
    items(photos) { photo ->
        PhotoItem(photo)
    }
}

LazyVerticalGrid, öğeler için bir genişlik belirtmenizi sağlar, ardından ızgara sütuna sığdırırsınız. Kalan genişlik eşit olarak dağıtılır sütun sayısı hesaplandıktan sonra bu değerleri görebilirsiniz. Bu uyarlanabilir boyutlandırma yöntemi, özellikle tüm öğeleri görüntüleme farklı ekran boyutlarında.

Kullanılacak sütun sayısını tam olarak biliyorsanız bunun yerine bir şunun örneği: GridCells.Fixed gereken sütun sayısını içerir.

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 aralığınıspan LazyGridScope DSL item ve items yöntemleri. maxLineSpan span kapsamının değerlerinden biri, özellikle uyarlanabilir boyutlandırma, çünkü sütun sayısı sabit değildir. 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, kademeli bir öğe ızgarası oluşturmanızı sağlayan composable'lardır. Öğeleri dikey olarak kaydırılabilir bir sayfada gösteren dikey geçişli ızgara birden fazla sütuna yayılan ve her bir öğenin ayrı ayrı görebilirsiniz. Tembel yatay ızgaralar, tablodaki öğe içeren yatay eksen.

Aşağıdaki snippet, LazyVerticalStaggeredGrid kullanımına ilişkin temel bir örnektir öğe başına 200.dp genişlikle:

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()
)

Şekil 1. Tembel dikey ızgara örneği
'nı inceleyin.

Sabit sayıda sütun ayarlamak için: StaggeredGridCells.Adaptive yerine StaggeredGridCells.Fixed(columns). Bu, mevcut genişliği sütun (veya bir öğe için satır) her bir öğe, bu genişliği (ya da belirli bir pencere için bu yatay ızgara):

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&#39;da kademeli resim ızgarası
Şekil 2. Sabit sütunlara sahip kademeli dikey ızgara örneği
'nı inceleyin.

İçerik dolgusu

Bazen içeriğin kenarlarına dolgu eklemeniz gerekir. Tembel bileşenlerden yararlanarak, PaddingValues desteklemesi için contentPadding parametresine eklemeniz gerekir:

LazyColumn(
    contentPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp),
) {
    // ...
}

Bu örnekte, yatay kenarlara (sol ve alt kenarlara) 16.dp oranında dolgu ekliyoruz. sağda), ardından içeriğin üst ve alt kısmına 8.dp tuşlarına basın.

Bu dolgunun LazyColumn kendisi. Yukarıdaki örnekte ilk öğeye 8.dp eklenir üst kısmına dolgu eklerse son öğe, en alta 8.dp ve tüm öğeler eklenir sol ve sağ tarafta 16.dp dolgu olacak.

İçerik aralığı

Öğeler arasında boşluk eklemek için şunları kullanabilirsiniz: Arrangement.spacedBy(). 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 bir öğenin durumu, öğenin öğe içindeki konumuna göre belirlenir. ya da çizelgeyi seçin. Ancak bu durum, veri kümesinin değişmesi veya konum değişikliği hatırlanan durumların etkin şekilde kaybedilmesine neden olabilir. Tahmin edebileceğiniz gibi LazyColumn içindeki LazyRow senaryosunda satır, öğe konumunu değiştirirse bunun ardından kullanıcı, satırdaki 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. Sabit bir anahtar sağlamak, öğe durumunun ve veri kümesi değişiklikleri arasında tutarlılık 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ırlanan durum içeriyorsa anahtar ayarlamak Konumu değiştiğinde bu durumu öğeyle birlikte taşımak için Oluştur'u tıklayın.

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ü şu tarafından desteklenmelidir: Bundle, Android’in etkinlik yeniden oluşturulduğunda geçerli olur. Bundle, temel öğeler, emin olun.

LazyColumn {
    items(books, key = {
        // primitives, enums, Parcelable, etc.
    }) {
        // ...
    }
}

İçerideki rememberSaveable öğesinin için anahtarın Bundle tarafından desteklenmesi gerekir. composable adlı öğe, Etkinlik yeniden oluşturulduğunda geri yüklenebilir. kaydırdığınızda görünür.

LazyColumn {
    items(books, key = { it.id }) {
        val rememberedValue = rememberSaveable {
            Random.nextInt()
        }
    }
}

Öğe animasyonları

RecyclerView widget'ını kullandıysanız öğenin animasyon otomatik olarak değiştirebilir. Tembel düzenler, öğelerin yeniden sıralanması için aynı işlevi sağlar. API basittir; tek yapmanız gereken animateItemPlacement değiştiricisi:

LazyColumn {
    items(books, key = { it.id }) {
        Row(Modifier.animateItemPlacement()) {
            // ...
        }
    }
}

Şunlara ihtiyacınız varsa özel animasyon spesifikasyonu bile sağlayabilirsiniz:

LazyColumn {
    items(books, key = { it.id }) {
        Row(
            Modifier.animateItemPlacement(
                tween(durationMillis = 250)
            )
        ) {
            // ...
        }
    }
}

Yeni öğeleri bulabilmek için öğelerinize anahtar koyduğunuzdan emin olun konumunu değiştirebilirsiniz.

Yeniden sıralamaların yanı sıra, ekleme ve kaldırma işlemleri için öğe animasyonları geliştirme aşamasındadır. İlerleme durumunu şuradan takip edebilirsiniz: sorun 150812265.

Yapışkan başlıklar (deneysel)

"Yapışkan başlık" kalıbı, gruplandırılmış verilerin listesini görüntülerken faydalıdır. Aşağıda her kişinin iletişim bilgilerine göre gruplandırılmış bir "kişi listesi" örneğini görebilirsiniz ilk:

Kişiler listesinde yukarı ve aşağı kaydırılan bir telefonun videosu

LazyColumn ile sabit bir başlık oluşturmak için deneysel stickyHeader() işlevini kullanın:

@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 listeye ulaşmak için yapabilecekleriniz:

// 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 ile öğe düzenindeki değişikliklere tepki vermesi ve bunları dinlemesi gerekir. Tembel bileşenler, tembel bileşenleri kaldırarak bu kullanım alanını LazyListState:

@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 öğe. Bunun için LazyListState sağlar firstVisibleItemIndex ve firstVisibleItemScrollOffset özellikler.

Kullanıcının kaydırarak ilk öğeyi geçip geçmediğine bağlı olarak bir düğmeyi 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 kompozisyonda okumak, güncelleme yapmanız gerektiğinde yararlıdır kullanıcı arayüzü composable'ları oluşturur, ancak etkinliğin aynı bileşimde ele alınacaktır. Bunun sık karşılaşılan bir örneği, belirli bir noktayı kaydırdıktan sonra analiz etkinliği. Bunu yapmak için etkili bir şekilde, snapshotFlow():

val listState = rememberLazyListState()

LazyColumn(state = listState) {
    // ...
}

LaunchedEffect(listState) {
    snapshotFlow { listState.firstVisibleItemIndex }
        .map { index -> index > 0 }
        .distinctUntilChanged()
        .filter { it }
        .collect {
            MyAnalyticsService.sendScrolledPastFirstItemEvent()
        }
}

LazyListState, şu anda görüntülenmekte olan tüm öğeler hakkında bilgi de sağlar ekranda gösterilir ve bunların sınırları layoutInfo Bkz. LazyListLayoutInfo daha fazla bilgi için.

Kaydırma konumunu kontrol etme

Ayrıca, kaydırma konumuna tepki vermenin yanı sıra uygulamaların, kaydırma konumunu da kontrol edebilirsiniz. LazyListState scrollToItem() üzerinden bunu destekler işlevini "hemen" kaydırma konumu ve animateScrollToItem() Örneğin, animasyon (yumuşak kaydırma olarak da bilinir) ile kayan resim:

@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 şunları yapmasına olanak tanır: büyük öğe listelerini destekler, listenin küçük parçalarının yüklenmesi ve görüntülenmesi gerekir. 3.0 ve sonraki sürümler, androidx.paging:paging-compose kitaplığı.

Sayfalandırılmış içerik listesini görüntülemek için collectAsLazyPagingItems() fonksiyonunu çağırın ve daha sonra, döndürülen LazyPagingItems LazyColumn içinde items() adlı yere. Görünümlerdeki Sayfalandırma desteğine benzer şekilde item değerinin null olup olmadığını kontrol ederek veriler yüklenirken yer tutucuları görüntüler:

@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()
            }
        }
    }
}

Tembel düzenlerin kullanımıyla 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 boyutlu öğeler kullanmaktan kaçının

Bu durum, örneğin eşzamansız olarak yapmayı beklediğiniz senaryolarda gerçekleşebilir daha sonra listenizin öğelerini doldurmak için resimler gibi bazı verileri alabilir. Bu, Tembel düzenin ilk 0 piksel olduğundan ve hepsine sığdırabileceğinden görünüm. Öğeler yüklendikten ve yükseklikleri genişletildikten sonra, Tembel düzenler oluşturulan diğer öğeleri de siler ve gereksiz yere çünkü görüntü alanına sığmazlar. Bunu önlemek için öğelerinize varsayılan boyutlandırmayı ayarlamanız gerekir. Böylece, Tembel düzen görüntü alanına sığabilen öğelerin doğru hesaplanması:

@Composable
fun Item(imageUrl: String) {
    AsyncImage(
        model = rememberAsyncImagePainter(model = imageUrl),
        modifier = Modifier.size(30.dp),
        contentDescription = null
        // ...
    )
}

Veriler tamamlandıktan sonra, öğelerinizin yaklaşık bedenini eşzamansız olarak yüklendiğinde, öğelerinizin bedenlerinin değişmediğinden aynısını yapın (örneğin, birkaç yer tutucu ekleyerek). Bu, kaydırmanın doğru konumda kalmasına yardımcı olur.

Aynı yönde kaydırılabilen bileşenleri iç içe yerleştirmekten kaçının

Bu, yalnızca önceden tanımlanmış bir öğe olmadan kaydırılabilir alt öğelerin iç içe yerleştirildiği durumlar için geçerlidir aynı yönde başka bir kaydırılabilir üst öğe içinde boyutu vardır. Örneğin, sabit yüksekliği olmayan bir alt LazyColumn öğesini dikey olarak kaydırılabilir bir öğenin içine yerleştir Column ebeveyn:

// throws IllegalStateException
Column(
    modifier = Modifier.verticalScroll(state)
) {
    LazyColumn {
        // ...
    }
}

Bunun yerine, tüm composable'larınızı sarmalayarak aynı sonucu elde edebilirsiniz. LazyColumn ve DSL'yi kullanarak farklı türde içerik. Bu, hem tekli öğelerin hem de birden çok liste öğesinin atanmasına olanak tanır. tek bir yerden kontrol edebilirsiniz:

LazyColumn {
    item {
        Header()
    }
    items(data) { item ->
        PhotoItem(item)
    }
    item {
        Footer()
    }
}

Farklı yön düzenlerini iç içe yerleştirdiğiniz durumlar için örneğin, kaydırılabilir üst Row ve alt LazyColumn öğelerine izin verilir:

Row(
    modifier = Modifier.horizontalScroll(scrollState)
) {
    LazyColumn {
        // ...
    }
}

Aynı yön düzenlerini kullanmaya devam ettiğiniz ancak iç içe yerleştirilmiş alt öğelere sabit bir boyuttur:

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 alarak öğeleri bir düzende yerleştirir. farklı öğelermiş gibi davranırlar. Ancak bunun için bazı işaretler bulabilirsiniz.

Birden fazla öğe bir öğenin parçası olarak yayınlandığında bir varlık gösterir, yani artık ayrı ayrı oluşturulamaz. Eğer öğesi ekranda görünür hale gelirse, oluşturulması ve ölçülmesi gerekir. Bu, kullanılırsa performansı düşürebilir aşırıya kaçmamak gerekir. Tüm öğeleri tek bir öğeye koymanın ekstrem bir örneği Bu, Tembel düzenlerin kullanılmasının amacını tamamen ortadan kaldırır. Potansiyelden farklı olarak performans sorunları yaşıyorsanız, bir öğeye daha fazla öğe koymak scrollToItem() ve animateScrollToItem().

Bununla birlikte, bir öğeye birden fazla öğe yerleştirmenin geçerli kullanım alanları vardır. Mesela bir listeye ayırıcılar eklemek. Ayırıcıların kaydırmayı değiştirmesini istemiyorsunuz bağımsız unsurlar olarak değerlendirilmemeleri gerekir. Ayrıca, performans bölenler küçük olduğundan etkilenmez. Bir ayırıcının büyük olasılıkla öğe görünür hale gelmeden önce görünür; böylece önceki öğenin parçası olabilirler öğe:

LazyVerticalGrid(
    columns = GridCells.Adaptive(100.dp)
) {
    item { Item(0) }
    item {
        Item(1)
        Divider()
    }
    item { Item(2) }
    // ...
}

Özel düzenlemeleri kullanmayı düşünün

Tembel listelerde genellikle birçok öğe bulunur ve bunlar, listenin boyutundan daha fazla kaydırma kapsayıcısını kullanın. Ancak, listeniz az sayıda öğeyle doldurulduğunda, bunların nasıl konumlandırılacağına dair daha belirli gereklilikleri olabilir. görüntü alanında olması gerekir.

Bunun için özel sektör Arrangement LazyColumn'a iletebiliriz. Aşağıdaki örnekte, TopWithFooter nesnenin yalnızca arrange yöntemini uygulaması gerekir. İlk olarak, videoyu öğeleri üst üste koyacaksınız. İkinci olarak, kullanılan toplam yükseklik alt görüntü alanı yüksekliğini belirlerse alt bilgi 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 adlı kullanıcıyı eklemeyi düşünün

Lazy'nizin performansını en üst düzeye çıkarmak için Compose 1.2'den başlayın. veya düzene eklemek için contentType listelerinizdeki ya da ızgaralarınızda. Bu, her biri için içerik türünü belirtmenize olanak tanır. bir liste veya ızgara oluşturduğunuz durumlarda, düzenin öğe türünden bahsedeceğiz:

LazyColumn {
    items(elements, contentType = { it.type }) {
        // ...
    }
}

contentType Oluştur, yalnızca besteleri yeniden kullanabilir aynı türden öğeler arasında olmalıdır. Yeniden kullanmak aynı yapıda öğeler oluşturmak, içerik türlerinin sağlanması, Oluşturma işlemi, tamamen aynı olan A türü bir öğe oluşturmaya B türünde farklı bir öğedir. Bu, kompozisyonun faydalarını en üst düzeye çıkarmaya ve Tembel düzen performansınız.

Performansı ölçme

Tembel düzenin performansını yalnızca yayınlama modu ve R8 optimizasyonunun etkin olduğu anlamına gelir. Hata ayıklama derlemelerinde, Geç düzen Kaydırma daha yavaş görünebilir. Daha fazla bilgi için Performans oluşturun.

ziyaret edin.