1

我需要检查某个LazyColumn项目何时进入视图,一旦出现,onItemWithKeyViewed()只回调一次以通知该项目已被查看。我的尝试:

@Composable
fun SpecialList(
    someItems: List<Things>,
    onItemWithKeyViewed: () -> Unit
) {
    val lazyListState = rememberLazyListState()

    if (lazyListState.isScrollInProgress) {
        val isItemWithKeyInView = lazyListState.layoutInfo
            .visibleItemsInfo
            .any { it.key == "specialKey" }
        if (isItemWithKeyInView) {
            onItemWithKeyViewed()
        }
    }

    LazyColumn(
        state = lazyListState
    ) {
        items(items = someItems) { itemData ->
            ComposableOfItem(itemData)
        }
        item(key = "specialKey") {
            SomeOtherComposable()
        }
    }
}

我的方法的问题是我注意到列表滚动性能严重下降并丢失帧。我意识到这可能是因为它正在检查每一帧上的所有可见项目键?

此外,onItemWithKeyViewed()当前被多次调用,而不仅仅是第一次被查看。

onItemWithKeyViewed()有没有一种更有效的方法可以只在第一次查看项目时进行单个回调"specialKey"

4

1 回答 1

1
  1. 在这种情况下,当您有一个经常更新的状态时,您应该使用derivedStateOf: 这将仅在计算结果实际发生变化时才导致重新组合。
  2. onItemWithKeyViewed您不应该直接在可组合构建器中调用副作用(即调用)。通常,您应该改用其中一种特殊的副作用功能LaunchedEffect- 这可以确保不会重复该操作。您可以在Thinking in Compose和副作用文档中找到有关此主题的更多信息。
val isItemWithKeyInView by remember {
    derivedStateOf {
        lazyListState.isScrollInProgress &&
                lazyListState.layoutInfo
                    .visibleItemsInfo
                    .any { it.key == "specialKey" }
    }
}
if (isItemWithKeyInView) {
    LaunchedEffect(Unit) {
        onItemWithKeyViewed()
    }
}
于 2022-02-02T06:26:05.973 回答