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
工具包中的RecyclerView
和ListView
。
可以使用for
循环将Column
中的所有组件放在VerticalScroller
中,但这会导致丢帧和大量项目的性能下降。
注意:这是一个规范的自我回答问题,以抢占/处理类似问题
【问题讨论】:
【参考方案1】:Jetpack Compose 中 RecyclerView
或 ListView
的等效组件是 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 在以前的版本中称为 AdapterList
、LazyColumnItems
/LazyRowItems
和 LazyColumnFor
/LazyRowFor
。
【讨论】:
谢谢。我想知道使用LazyColumnFor
或LazyRowFor
是否还有任何性能提示?这方面的信息现在在网上真的很少见。即使在发布模式下也确实很慢,我用ConstraintLayout
可组合进行了测试,它有一些图像、一些文本和三个按钮。
对于更复杂的项目,在 RecyclerViews 中,项目 ID 和项目内容之间存在差异,以识别内容更改与新项目。你知道如何在LazyColumnFor
中实现这种差异化吗?
@SebasLG 目前没有这样的区别。在很大程度上是没有必要的:如果你使用 Compose 状态变量来保存变化的内容,孩子将重新组合而不被视为新项目。
@RosenDimov 你有消息吗?我正在拼命尝试使用 LazyColumn,但目前性能真的很差。
@sachadso,现在看来还为时过早,我想更多的优化即将到来。我上次尝试使用alpha06
,与我记录的这个问题(以及其他一些问题)相关,有轻微的提升:issuetracker.google.com/issues/165028371 但与RecyclerView
的行为仍然相去甚远。【参考方案2】:
[ScrollableColumn] 用于垂直滚动列表 [ScrollableRow] 用于水平滚动列表dev.16 中的更新
从ListCardViewTemplate检查它的实现
您可以使用在 dev.14 预览版中重命名的 AdapterList
在 JetpackCompose 中获得与 RecyclerView
或 ListView
相同的本质。
[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)
从我的角度来看,如果您的项目布局很复杂,
LazyColumnItem
或LazyRowItem
将无法正常工作,因为与VerticalScroller
在这种情况下工作正常相比,它会卡在列表中。
【讨论】:
LazyRowItems
和 LazyColumnItems
现在已弃用,取而代之的是 LazyRowFor
和 LazyColumnFor
根据文档:developer.android.com/reference/kotlin/androidx/compose/…
是的,在 dev.16 中他们更新了它。我修改了答案以上是关于RecyclerView 或 ListView 的 Jetpack Compose 等价物是啥?的主要内容,如果未能解决你的问题,请参考以下文章
Android:重新绑定 ListView 或 RecyclerView 而不刷新 Header
为 listview 或 recyclerview 更改单个项目的布局
排列 listView 或 recyclerView 项目,如chipGroup