Closed JoeSteven closed 8 months ago
I'm running into this issue too. It seems like on desktop DefaultScrollableState.scroll()
isn't being called. Instead, dispatchRawDelta()
is. Since that second method doesn't affect isScrollInProgress
, it's always false.
I think it's because of the touchScrollable()
vs mouseScroll()
differences here.
Encountered this problem while trying to synchronize the scroll position of multiple parallel LazyColumn
s.
Inspired by these answers on StackOverflow:
https://stackoverflow.com/questions/71206165/shared-lazyliststate-across-multiple-lazyrow-result-in-strange-behavior?noredirect=1&lq=1, https://stackoverflow.com/questions/69565303/scroll-multiple-lists-at-different-speeds-in-jetpack-compose/69613111#69613111
Temporarily worked around this by using firstVisibleItemIndex
and firstVisibleItemScrollOffset
as triggers to perform the scrollToItem
:
val idx = lazyListStateA.firstVisibleItemIndex
val off = lazyListStateA.firstVisibleItemScrollOffset
LaunchedEffect(idx, off) {
lazyListStateB.scrollToItem(idx, off)
}
It should be mitigated after implementing smooth (animated) scrolling, but if you need to check if there was a scroll, you should subscribe to firstVisibleItemIndex
and firstVisibleItemScrollOffset
(as @SebastianAigner mentioned above) instead:
snapshotFlow { listState.firstVisibleItemIndex to listState.firstVisibleItemScrollOffset }
.distinctUntilChanged()
Semantics of isScrollInProgress
returns true
only if we have a scroll across multiple frames, i.e. we have something continuous, not instant. Unlike dragging where we can detect start, move and end of gesture (in different frames), it's not a case with single event from mouse wheel. As I mentioned above it can be mitigated by introduction animated transaction, but still even after that, there can be a situation where transaction doesn't have an animation, and scroll position will be changed from one place to another in one single frame.
It worth to mention that smooth (animated) scrolling is merged, so currently there is a TODO in code about this flag. Please note that it's still not exactly about mouse wheel, since it's just single-frame event (as explained above).
ScrollState
has a similar field. It's also always false
on desktop.
It should be mitigated after implementing smooth (animated) scrolling, but if you need to check if there was a scroll, you should subscribe to
firstVisibleItemIndex
andfirstVisibleItemScrollOffset
(as @SebastianAigner mentioned above) instead:snapshotFlow { listState.firstVisibleItemIndex to listState.firstVisibleItemScrollOffset } .distinctUntilChanged()
Semantics of
isScrollInProgress
returnstrue
only if we have a scroll across multiple frames, i.e. we have something continuous, not instant. Unlike dragging where we can detect start, move and end of gesture (in different frames), it's not a case with single event from mouse wheel. As I mentioned above it can be mitigated by introduction animated transaction, but still even after that, there can be a situation where transaction doesn't have an animation, and scroll position will be changed from one place to another in one single frame.
I tried this
LaunchedEffect(lazyListState) {
snapshotFlow {
lazyListState.firstVisibleItemIndex to
lazyListState.firstVisibleItemScrollOffset
}.distinctUntilChanged().collect { (i, offset) ->
println("Changed")
lazyListState.scrollToItem(i, offset)
}
}
and it only triggers twice and then scrolling stops working.
@aljohnston112 It's about #3366. Fixed in https://github.com/JetBrains/compose-multiplatform-core/pull/696 It was because conflicting simultaneous animations (triggered by mouse wheel and by your scrollToItem
)
Please check the following ticket on YouTrack for follow-ups to this issue. GitHub issues will be closed in the coming weeks.
Compose-jb version: 1.0.0-beta5 kotlin version: 1.5.31 Hi, I want to save the first item position after scroll, here is my code:
it works perfect on Android, isScrollInProgress updated every time the list start to scroll and stop scroll
But on desktop (MacOS BigSur/ Windows10) I found that isScrollInProgress
is always false
even list is clearly in scroll。BTW, I've tested this code both on my project and Compose-jb/examples/imageViewer, the results is the same.