在Jetpack Compose中,如何在仅布局可见项目的同时显示大的数据列表,而不是在初始布局过程中组合和布局每个项目?这将类似于View工具包中的RecyclerViewListView.

可以使用for循环将所有组件放置在VerticalScroller中的Column中,但这会导致帧丢失,并且在大量项目上性能不佳.


Note: this is intended as a canonical self-answered question to pre-empt/handle similar questions

推荐答案

Jetpack Compose中RecyclerViewListView的等效组件为LazyColumn(垂直列表)和LazyRow(水平列表).它们仅构成和布置当前可见的项目.

您可以使用它,方法是将数据格式化为列表,并将其与@Composable回调一起传递,该回调将发出列表中给定项的UI.例如:

val myData = listOf("Hello,", "world!")
LazyColumn {
    items(myData) { item ->
        Text(text = item)
    }
}
val myData = listOf("Hello,", "world!")
LazyRow { 
    items(myData) { item ->
        Text(text = item)
    }
}

You can also specify individual items one at a time:

LazyColumn {
    item {
        Text("Hello,")
    }
    item {
        Text("world!")
    }
}
LazyRow { 
    item {
        Text("Hello,")
    }
    item {
        Text("world!")
    }
}

还有索引变体,除了项目本身之外,还提供集合中的索引:

val myData = listOf("Hello,", "world!")
LazyColumn {
    itemsIndexed(myData) { index, item ->
        Text(text = "Item #$index is $item")
    }
}
val myData = listOf("Hello,", "world!")
LazyRow { 
    itemsIndexed(myData) { index, item ->
        Text(text = "Item #$index is $item")
    }
}

在以前的版本中,这些API被称为AdapterListLazyColumnItems/LazyRowItemsLazyColumnFor/LazyRowFor.

Kotlin相关问答推荐

Lambda和普通Kotlin函数有什么区别?

Kotlin和JavaFX:绑定行为奇怪

如何编写带有依赖项的自定义Kotlin串行化程序?

collectAsState 未从存储库接收更改

为什么我的通用Kotlin函数中的这个转换未经判断?

将 java Optional 转换为 Kotlin Arrow Option

第二个协程永远不会执行

如何在 jOOQ 中两次加入同一张表?

Kotlin 日期格式从一种更改为另一种

使用 Kotlin 协程时 Room dao 类出错

Kotlin:内部类如何访问在外部类中声明为参数的变量?

Android数据绑定在自定义视图中注入ViewModel

Kotlin 中的 Java Scanner 相当于什么?

如何在使用 Gradle 的 AppEngine 项目中使用 Kotlin

Android Studio 将 Java 转换为 Kotlin 错误无法推断此参数的类型

使用导航组件在不同的图形之间导航

如何从协程范围返回值

如何序列化/反序列化Kotlin密封类?

在 kotlin 中,如何将主构造函数中的属性设置器设为私有?

Android Studio - java.io.IOException:无法生成 v1 签名