我想知道是否有一种方法或资源可供我参考,以便在滚动项目时对LazyRow产生副作用?副作用基本上是调用viewModel中的一个函数来更改列表状态的状态。
的全屏LazyRow项。
到目前为止,我已经尝试过NestedScrollConnection
class OnMoodItemScrolled : NestedScrollConnection {
override suspend fun onPostFling(consumed: Velocity, available: Velocity): Velocity {
viewModel.fetchItems()
return super.onPostFling(consumed, available)
}
}上面的问题是,副作用无论如何都要执行--尽管滚动后显示的项目与滚动之前相同。
我还试图按以下方式收集listState交互
val firstVisibleItem: Int = remember { sectionItemListState.firstVisibleItemIndex }
sectionItemListState.interactionSource.collectIsDraggedAsState().let {
if (firstVisibleItem != sectionItemListState.firstVisibleItemIndex) {
viewModel.fetchItems()
}
}上面的问题是,副作用将被执行,第二次可合成是第一次。
发布于 2022-12-02 09:02:33
您可以使用获取有关第一个可见项的信息,并存储此值。当值更改时,项目将向上滚动。
类似于:
@Composable
private fun LazyListState.itemIndexScrolledUp(): Int {
var previousIndex by remember(this) { mutableStateOf(firstVisibleItemIndex) }
return remember(this) {
derivedStateOf {
if (firstVisibleItemIndex > previousIndex) {
//scrolling up
previousIndex
} else {
- 1
}.also {
//Update the previous index
previousIndex = firstVisibleItemIndex
}
}
}.value
}然后:
val state = rememberLazyListState()
var index = state.itemIndexScrolledUp()
DisposableEffect(index){
if (index != -1) {
//...item is scrolled up
}
onDispose { }
}
LazyColumn(
state = state,
){
//...
}发布于 2022-12-02 11:32:46
我用一个有两个键的LaunchedEffect解决了我的问题。
val sectionItemListState = rememberLazyListState()
val flingBehavior = rememberSnapFlingBehavior(sectionItemListState)
var previousVisibleItemIndex by remember {
mutableStateOf(0)
}
val currentVisibleItemIndex: Int by remember {
derivedStateOf { sectionItemListState.firstVisibleItemIndex }
}
val currentVisibleItemScrollOffset: Int by remember {
derivedStateOf { sectionItemListState.firstVisibleItemScrollOffset }
}
LaunchedEffect(currentVisibleItemIndex, currentVisibleItemScrollOffset) {
if (previousVisibleItemIndex != currentVisibleItemIndex && currentVisibleItemScrollOffset == 0) {
// The currentVisible item is different than the previous one && it's fully visible
viewModel.fetchItems()
previousVisibleItemIndex = currentVisibleItemIndex
}
}使用currentVisibleItemIndex和currentVisibleItemScrollOffset作为键将确保只要其中一个更改,就会触发LaunchedEffect。此外,检查previousVisibleItemIndex是否与currentVisibleItemIndex不同,将确保只有在可见项发生更改时才触发此效果。但是,如果使用已经部分滚动,那么这个条件将是真正的也是,而且由于我有抓拍效果,它将回到以前的位置。这将导致触发效应两次。为了确保只有在实际上是滚动到下一个/先前完全可见的位置时才触发效果,我们需要依赖scrollOffset。
https://stackoverflow.com/questions/74649453
复制相似问题