【问题标题】:Handle scroll in Jetpack Compose `LazyLayout`在 Jetpack Compose `LazyLayout` 中处理滚动
【发布时间】:2022-10-23 22:04:46
【问题描述】:

最近LazyLayout for compose 被分享为实验性的尝试。它被其他惰性实现用于列表(列/行)和网格。我想尝试一下,并实现一个简单的自定义惰性布局来延迟滚动和显示项目(类似于LazyList)。下面的代码是虚拟的,但想法是在滚动偏移上做一些事情(在这个例子中,我放置了 3 个带有滚动偏移空间的项目)。

问题是,在滚动时,所有可组合项都会随着 layout 块的调用而消失,但它没有放置任何东西(只有初始组合)。答案可能在LazyListLazyGrid 的某个地方,但我想避免复制粘贴并逐步做一些事情。如果有人能对这个问题有所了解,我将不胜感激,如何实际处理LazyLayout 的滚动。

我尝试用verticalScroll 替换scrollable,但结果相同。

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun CustomLazyLayout(
    modifier: Modifier = Modifier,
    content: @Composable (String) -> Unit
) {
    val scrollState = rememberScrollState()
    var firstId by remember { mutableStateOf(0) }
    var firstOffset by remember { mutableStateOf(0) }
    LazyLayout(
        modifier = modifier
            .clipScrollableContainer(Orientation.Vertical)
            .scrollable(
                orientation = Orientation.Vertical,
                reverseDirection = false,
                interactionSource = null,
                flingBehavior = ScrollableDefaults.flingBehavior(),
                state = scrollState,
                overscrollEffect = ScrollableDefaults.overscrollEffect(),
                enabled = true
            ),
        itemProvider = object : LazyLayoutItemProvider {
            override val itemCount: Int
                get() = 10

            @Composable
            override fun Item(index: Int) {
                content("$index")
            }

        },
        measurePolicy = { constraints ->
            val list = mutableListOf<Placeable>()

            var i = firstId
            while(i < firstId+3) {
                val m = measure(i, constraints)
                if (m.isNotEmpty()) {
                    list.add(m[0])
                }
                ++i
            }
            val height = list.first().measuredHeight
            var positionY = 0
            layout(constraints.maxWidth, constraints.maxHeight) {
                for (placeable in list) {
                    placeable.place(0, positionY + scrollState.value)
                    positionY += height
                }
            }
        }
    )

【问题讨论】:

    标签: android android-jetpack-compose


    【解决方案1】:

    如果我将scrollableState 移出layout 块到measurePolicy,问题就解决了。准确地说,这段代码实际上会模仿常规滚动效果:

            var positionY = -scrollState.value
            layout(constraints.maxWidth, constraints.maxHeight) {
                for (placeable in list) {
                    placeable.place(0, positionY)
                    positionY += height
                }
            }
    

    以前在滚动时只调用了 layout 块。现在两者都是(测量和布局)。我仍然不确定我是否以正确的方式进行操作,但是项目只组成一次,所以我猜它正在工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-26
      • 1970-01-01
      • 2021-10-27
      • 1970-01-01
      • 2023-01-07
      • 1970-01-01
      • 2023-02-04
      • 1970-01-01
      相关资源
      最近更新 更多