Closed alexjlockwood closed 2 years ago
A quick update... I did end up finding a workaround that seems to work, but it wasn't very intuitive. Essentially it required creating a custom FlingBehavior
that wraps around the default:
@Stable
internal class CustomFlingBehavior(
// Can just be `PagerDefaults#defaultPagerFlingConfig()`
private val flingBehavior: FlingBehavior,
) : FlingBehavior {
var isSettling by mutableStateOf(false)
private set
override suspend fun ScrollScope.performFling(initialVelocity: Float) = try {
isSettling = true
with(flingBehavior) { performFling(initialVelocity) }
} finally {
isSettling = false
}
}
Then pass this FlingBehavior
to HorizontalPager(flingBehavior = myFlingBehavior)
. Then in order to determine whether a scroll was initiated via a scroll vs. a fling, you would just use myFlingBehavior.isSettling
.
Like I said, it works... but not very straightforward and would be nice if this extra fling state could be consolidated under PagerState
somehow.
This is more of a question for ScrollableState
since all of that API comes from there.
/cc @matvei-g
We expose InteractionSource as a part of LazyListState
and ScrollState
. This InteractionSource emmits DragInteraction.Start when drag started allowing developers to react to this emission or to the fact that's it's gone (DragInteraction.Stop emitted).
Does it make sense to provide the same InteractionSource in the Pager as well?
@chrisbanes Yeah that's fair, I was thinking that as well. Makes sense for accompanist to stay consistent with whatever API ScrollableState
uses.
@matvei-g I like the idea of adding an InteractionSource
property to PagerState
as well!
InteractionSource
looks good to me, I'll whip up a quick PR now. Should this be part of the ScrollableState
contract?
// EDIT: just saw that it's part of the Modifier.scrollable
API. Ignore this.
ViewPager
andViewPager2
have an API calledOnPageChangeCallback#onPageScrollStateChanged()
which allows you to determine whether the current scroll is settling, programatically initiated (i.e. part of a "fake drag" usingViewPager2#fakeDragBy()
), or part of an active gesture.Currently there doesn't seem to be a similar API for
PagerState
, asPagerState#isScrollInProgress
returns whether there is an active scroll. but provides no information about how it was initiated or whether there is still an active gesture happening.This API would be ideal as in some cases you want to react to a view pager page change, but only once the user has finished interacting with the screen and the next target page is known for certain.