在 Jetpack Compose 的 LazyColumn 中对第一个顶部 StickyHeader 进行动画处理

问题描述 投票:0回答:1

当用户开始滚动标题组中的项目时,我尝试仅对顶部粘性标题进行动画处理。下面的代码在向上或向下滚动时为所有标题设置动画。

一种方法是获取第一个可见标头的索引。但是,firstVisibleItemIndex 表示组中的第一项,而不是标题。看来compose LazyListState不支持获取stickyHeader索引。

是否可以根据firstVisibleItemScrollOffset和NestedScrollConnection中onPreScroll获取的偏移量来计算索引?

也许还有另一种方法可以仅对顶部标题进行动画处理?

懒列

    val listState = rememberLazyListState()
    val firstVisibleItemIndex = remember { derivedStateOf { listState.firstVisibleItemIndex } }
    val firstVisibleItemScrollOffset = remember { derivedStateOf { listState.firstVisibleItemScrollOffset } }

LazyColumn(
        state = listState,
        modifier = modifier.nestedScroll(nestedScrollConnection)
    ) {
        categories.forEachIndexed { index, category ->
            stickyHeader {
                SessionCard(
                    firstVisibleItemIndex = firstVisibleItemIndex.value,
                    firstVisibleItemScrollOffset = firstVisibleItemScrollOffset.value,
                    scale = scale.value,
                    index = index
                )
            }
            items(category.items) { text ->
                CategoryItem(text)
            }
        }
    }

规模

val scale = remember { mutableStateOf(1f) }
    val nestedScrollConnection = remember {
        object : NestedScrollConnection {
            override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
                if (available.y < 0) {
                    scale.value = max(0.8f, scale.value - 0.01f)
                } else {
                    scale.value = min(1f, scale.value + 0.01f)
                }
                return Offset.Zero
            }
        }
    }

android android-jetpack-compose
1个回答
0
投票

我找到了这个问题的解决方案:

  1. 我在 StickyHeader() 中将一个键分配给类别名称

    stickyHeader(key = 类别.group.title)

  2. 然后,在onPReScroll中我检查了visibleItem键,并更新了比例

    val itemKey = remember { mutableStateOf("") }
    val scale = remember { mutableFloatStateOf(1f) }
    ...
    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
    val visibleItemsInfo = listState.layoutInfo.visibleItemsInfo.firstOrNull()
    if (visibleItemsInfo?.key != itemKey.value) {
       itemKey.value = visibleItemsInfo?.key.toString()
    }
    
    if (available.y < 0) {
       val newScale = max(scaleTo, scale.floatValue - scaleStep)
       scale.floatValue = newScale
    } else {
        val newScale = min(1f, scale.floatValue + scaleStep)
        scale.floatValue = newScale
    }
    
  3. 接下来在 LazyColumn 中我检查了可见的 StickyHeader 卡是否应该动画化

    粘性标题卡( shouldScale = item.group.title == itemKey.value, 比例尺=比例尺.floatValue )

  4. 在卡片中,当 shouldScale 为 true 时,我触发了动画。

    var scaleAnim 记住 { mutableFloatStateOf(1f) } LaunchedEffect 在此处输入代码(scale) { 如果(应该缩放){ 缩放动画 = 缩放 } }

© www.soinside.com 2019 - 2024. All rights reserved.