当用户开始滚动标题组中的项目时,我尝试仅对顶部粘性标题进行动画处理。下面的代码在向上或向下滚动时为所有标题设置动画。
一种方法是获取第一个可见标头的索引。但是,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
}
}
}
我找到了这个问题的解决方案:
我在 StickyHeader() 中将一个键分配给类别名称
stickyHeader(key = 类别.group.title)
然后,在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
}
接下来在 LazyColumn 中我检查了可见的 StickyHeader 卡是否应该动画化
粘性标题卡( shouldScale = item.group.title == itemKey.value, 比例尺=比例尺.floatValue )
在卡片中,当 shouldScale 为 true 时,我触发了动画。
var scaleAnim 记住 { mutableFloatStateOf(1f) } LaunchedEffect 在此处输入代码(scale) { 如果(应该缩放){ 缩放动画 = 缩放 } }