0

我正在使用 Compose 制作的搜索页面,一切正常,除了在数据更改时返回到第一项LazyColumn的想要行为。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使用itemsListas key,但什么也没发生。

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

4

1 回答 1

0

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

为了使其工作,您可以更改itemsListList<DataType>传递普通列表,例如itemsList = mutableStateList.toList()- 它会强制整个视图重新组合。


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

LaunchedEffect(itemsList.toList()) {
}
于 2021-12-18T01:43:56.400 回答