我有一个简单的可组合函数,其中包含LazyColumn:

@Composable
fun MyScreen(itemList: List<Item>) {
    LazyColumn {
        intems(itemList) {
            ...
        }
    }
}

一切都很好,但是当滚动达到某个位置索引时,我的视图状态(itemList)应该会改变.这就是为什么我在可组合函数中添加以下行:

@Composable
fun MyScreen(itemList: List<Item>) {
    val lazyListState = rememberLazyListState()
    viewModel.onPositionChanged(lazyListState.firstVisibleItemIndex)
    LazyColumn(state = lazyListState) {
        intems(itemList) {
            ...
        }
    }
}

一切正常,但性能明显下降.我怎么能修好它?

推荐答案

这里有两个问题:

  1. 当你直接在Composable with lazyListState.firstVisibleItemIndex中读取状态时,这会导致继续重新定位——每次lazyListState的任何部分发生变化时,例如在每个滚动的像素上.
  2. 您直接从composable拨打viewModel.onPositionChanged电话.建议使用特殊的副作用函数进行此类调用,阅读thinking in compose和副作用documentation中的更多主题.

在这种情况下,LaunchedEffectsnapshotFlow可以这样使用:

LaunchedEffect(Unit) {
    snapshotFlow { lazyListState.firstVisibleItemIndex }
        .collect(viewModel::onPositionChanged)
}

当需要根据列表状态更新视图时,也可能会遇到同样的问题.在这种情况下,应该使用derivedStateOf:只有当计算值实际发生变化时,才会导致重新编译.

val firstVisibleItemIndex by remember {
    derivedStateOf {
        lazyListState.firstVisibleItemIndex
    }
}

Android相关问答推荐

Jetpack Compose Scaffold—content不在TopAppBar下面开始'

了解数据加载在Kotlin中的工作原理

房间DB:UPSERT返回什么?

从单元测试访问RES/RAW文件

StateFlow集合AsState没有更新他的值Jetpack Compose导航

Android App Google AdMob";广告加载失败:3;带有测试ID,&q;广告加载失败:1 for My Gahad

如何使用进度条和返回函数进行API调用,同时在Android上使用Kotlin保持高效?

Jetpack Compose-如何在进入新产品线之前删除单词?

可组合:don';t剪辑视图

为什么第二个代码可以安全地在 map 中进行网络调用,因为它已被缓存?

如何在我的sqlite数据库中获取某个玩家的分数

Android Drawable文件夹中的图像显示模糊

如何在 Jetpack Compose 中对数据类进行 Parcelize

在段的中心绘制饼图(甜甜圈图)的图例

系统导航栏在某些场景下应用了深色效果

在Android RoomDB中使用Kotlin Flow和删除数据时如何解决错误?

状态更改后 colored颜色 未正确更改

在 Kotlin 中设置 startActivity() 时类型不匹配

房间实时数据:启动时崩溃

dagger2 抛出错误:如果没有 @Provides-annotated 方法就无法提供.在我的 android 项目的构建中