【问题标题】:Jetpack Compose, how to reset LazyColumn position when new data are set?Jetpack Compose,设置新数据时如何重置 LazyColumn 位置?
【发布时间】:2022-01-20 11:26:04
【问题描述】:

我正在使用 LazyColumn 在 Compose 中创建搜索页面,一切正常,除了 LazyColumn 在数据更改时返回到第一项的想要行为。

这是我对惰性列的实际实现:

@Composable
fun <DataType : Any> GenericListView(
    itemsList: SnapshotStateList<DataType>, // this list comes from the search page viewmodel
    modifier: Modifier = Modifier.fillMaxSize(),
    spacing: Dp = 24.dp,
    padding: PaddingValues = PaddingValues(0.dp),
    item: @Composable (DataType) -> Unit
) {

    val listState: LazyListState = rememberLazyListState()
    val coroutineScope = rememberCoroutineScope()

    LazyColumn(
        verticalArrangement = Arrangement.spacedBy(spacing),
        state = listState,
        modifier = modifier.padding(padding)
    ) {
        items(itemsList) {
            item(it)
        }
    }

    SideEffect {
        Log.i("->->->->->->->", "side effect launched")
        coroutineScope.launch {
            listState.scrollToItem(0)
        }
    }
}

正如文档所说,每次重构函数时都应该调用SideEffect, 但它似乎只能在带有SideEffect 断点的调试模式下工作,否则,它仅在第一次创建整个页面时才有效。

我已经尝试使用LaunchedEffect 而不是SideEffect,将itemsList 用作key,但没有任何反应。

为什么我的代码只能在调试模式下工作? 或者更好的是,在设置新数据时重置位置的现有解决方案?

【问题讨论】:

    标签: android kotlin android-jetpack-compose android-jetpack-compose-list


    【解决方案1】:

    SideEffect 不起作用,因为当 SnapshotStateList 更改时 Compose 实际上并没有重新组合整个视图:它看到只有 LazyColumn 正在使用这个状态值,所以只有这个函数需要重新组合。

    要使其正常工作,您可以将 itemsList 更改为 List&lt;DataType&gt; 并传递普通列表,例如 itemsList = mutableStateList.toList() - 它会强制整个视图重新组合。


    LaunchedEffect 与传递的SnapshotStateList 出于同样的原因不起作用:它比较状态容器的地址,而该地址没有改变。要比较项目本身,您可以再次将其转换为普通列表:在这种情况下,它将通过项目哈希进行比较。

    LaunchedEffect(itemsList.toList()) {
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 1970-01-01
      • 2021-11-09
      • 2021-06-01
      • 2022-08-20
      • 2023-02-26
      相关资源
      最近更新 更多