RecyclerView 或 ListView 的 Jetpack Compose 等价物是啥?

Posted

技术标签:

【中文标题】RecyclerView 或 ListView 的 Jetpack Compose 等价物是啥?【英文标题】:What is the Jetpack Compose equivalent of RecyclerView or ListView?RecyclerView 或 ListView 的 Jetpack Compose 等价物是什么? 【发布时间】:2020-07-01 01:43:15 【问题描述】:

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

可以使用for 循环将Column 中的所有组件放在VerticalScroller 中,但这会导致丢帧和大量项目的性能下降。


注意:这是一个规范的自我回答问题,以抢占/处理类似问题

【问题讨论】:

【参考方案1】:

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)
    

您还可以一次指定单个项目:

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

【讨论】:

谢谢。我想知道使用LazyColumnForLazyRowFor 是否还有任何性能提示?这方面的信息现在在网上真的很少见。即使在发布模式下也确实很慢,我用ConstraintLayout 可组合进行了测试,它有一些图像、一些文本和三个按钮。 对于更复杂的项目,在 RecyclerViews 中,项目 ID 和项目内容之间存在差异,以识别内容更改与新项目。你知道如何在LazyColumnFor 中实现这种差异化吗? @SebasLG 目前没有这样的区别。在很大程度上是没有必要的:如果你使用 Compose 状态变量来保存变化的内容,孩子将重新组合而不被视为新项目。 @RosenDimov 你有消息吗?我正在拼命尝试使用 LazyColumn,但目前性能真的很差。 @sachadso,现在看来还为时过早,我想更多的优化即将到来。我上次尝试使用alpha06,与我记录的这个问题(以及其他一些问题)相关,有轻微的提升:issuetracker.google.com/issues/165028371 但与RecyclerView 的行为仍然相去甚远。【参考方案2】:

dev.16 中的更新

[ScrollableColumn] 用于垂直滚动列表 [ScrollableRow] 用于水平滚动列表

从ListCardViewTemplate检查它的实现


您可以使用在 dev.14 预览版中重命名的 AdapterList 在 JetpackCompose 中获得与 RecyclerViewListView 相同的本质。

[LazyColumnItems] 垂直滚动列表 [LazyRowItems] 用于水平滚动列表

查看文档中的内容:

它也被移动到lazy 子包中并分成两个文件。另外我重命名了参数:

    数据 -> 项目。这似乎比原始的更有意义 data itemCallback -> itemContent。这更有意义,我们 通常不要在 lambda 名称中使用单词回调,尤其是对于 可组合的 lambdas

查看使用方法:

@Composable
fun <T> LazyColumnItems(
  items: List<T>,
  modifier: Modifier = Modifier,
  itemContent: @Composable (T) -> Unit
) 
    LazyItems(items, modifier, itemContent, isVertical = true)

在.KT中

LazyColumnItems(items = (0..50).toList())  item ->
    cardViewImplementer(item)
 

从我的角度来看,如果您的项目布局很复杂,LazyColumnItemLazyRowItem 将无法正常工作,因为与 VerticalScroller 在这种情况下工作正常相比,它会卡在列表中。

【讨论】:

LazyRowItemsLazyColumnItems 现在已弃用,取而代之的是 LazyRowForLazyColumnFor 根据文档:developer.android.com/reference/kotlin/androidx/compose/… 是的,在 dev.16 中他们更新了它。我修改了答案

以上是关于RecyclerView 或 ListView 的 Jetpack Compose 等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Android:重新绑定 ListView 或 RecyclerView 而不刷新 Header

为 listview 或 recyclerview 更改单个项目的布局

排列 listView 或 recyclerView 项目,如chipGroup

RecyclerView 或 ListView 的 Jetpack Compose 等价物是啥?

Listview和RecyclerView区别

Android控件RecyclerView和ListView的异同