如何检查 Jetpack Compose 中列表项的可见性

Mar*_*rat 3 android android-jetpack-compose android-jetpack-compose-list android-jetpack-compose-lazy-column

FlatListofReact Native有一个属性viewabilityConfigCallbackPairs,您可以在其中设置:

viewabilityConfig: {
    itemVisiblePercentThreshold: 50,
    waitForInteraction: true,
  }
Run Code Online (Sandbox Code Playgroud)

以 50% 的阈值以及交互或滚动后检测列表的可见项目。

Jetpack Compose 也有类似的东西吗?

LazyListState一些布局信息。但我想知道这个用例是否有任何内置组件/属性。

编辑

我有一个卡片视图列表,我想检测哪些卡片项目(至少 50% 的卡片可见)在显示屏上可见。但只有当用户单击卡片或滚动列表时才需要检测到它。

Om *_*mar 14

要获取具有特定阈值的当前可见项目的更新列表,LazyListState可以使用。

LazyListState公开当前可见项目的列表List<LazyListItemInfo>visibility percent使用 offset和属性很容易计算size,因此可以将过滤器应用于 的可见列表visibility >= threshold

LazyListItemInfoindex属性,可用于映射LazyListItemInfo到传递给 的列表中的实际数据项LazyColumn

fun LazyListState.visibleItems(itemVisiblePercentThreshold: Float) =
    layoutInfo
        .visibleItemsInfo
        .filter {
            visibilityPercent(it) >= itemVisiblePercentThreshold
        }

fun LazyListState.visibilityPercent(info: LazyListItemInfo): Float {
    val cutTop = max(0, layoutInfo.viewportStartOffset - info.offset)
    val cutBottom = max(0, info.offset + info.size - layoutInfo.viewportEndOffset)

    return max(0f, 100f - (cutTop + cutBottom) * 100f / info.size)
}
Run Code Online (Sandbox Code Playgroud)

用法

val list = state.visibleItems(50f) // list of LazyListItemInfo
Run Code Online (Sandbox Code Playgroud)

该列表必须首先映射到 中的相应项目LazyColumn

val visibleItems = state.visibleItems(50f)
            .map { listItems[it.index] }
Run Code Online (Sandbox Code Playgroud)
@Composable
fun App() {
    val listItems = remember { generateFakeListItems().toMutableStateList() }

    val state = rememberLazyListState()

    LazyColumn(Modifier.fillMaxSize(), state = state) {
        items(listItems.size) {
            Item(listItems[it])
        }
    }

    val visibleItems by remember(state) {
      derivedStateOf {
        state.visibleItems(50f)
          .map { listItems[it.index] }
      }
    }
    LaunchedEffect(visibleItems) {
      Log.d(TAG, "App: $visibleItems")
    }
}

fun generateFakeListItems() = (0..100).map { "Item $it" }
Run Code Online (Sandbox Code Playgroud)

  • `layoutInfo.visibleItemsInfo` 强制重组,这会进入无限重组:https://issuetracker.google.com/issues/216499432 (3认同)