Reputation: 908
I'm using ViewPager2 and want to detect when the user swipes either to the left on the first page or the right on the last page.
I know this can be implemented using the old ViewPager
like discussed here, but this approach is not feasible since ViewPager2
is final and can't be subclassed.
ViewPager2
provides the OnPageChangeCallback but this can't be used either since there are no page events when swiping out of bounds.
Am I missing something?
Upvotes: 3
Views: 2037
Reputation: 325
thanks, @flauschtrud To handle better swapping right on the last index or swapping left to the first index of your child tab layout, I use this code for a challenge when I wanted to change paging on nested tab layouts because SwipeChangeListener could not detect swap to the left & right when you were on the first index or the last index of the tab layout item
yourChildViewPager.registerOnPageChangeCallback(object :
OnPageChangeCallback() {
private var settled = false
override fun onPageScrollStateChanged(state: Int) {
super.onPageScrollStateChanged(state)
if (state == SCROLL_STATE_DRAGGING) {
settled = false
}
if (state == SCROLL_STATE_SETTLING) {
settled = true
}
if (state == SCROLL_STATE_IDLE && !settled) {
if (yourChildViewPager.currentItem == 0) {
backDirectionToParentViewPager()
} else {
forwardDirectionToParentViewPager()
}
}
}
})
Note: You can handle disable or enable paging in your parent view pager (ViewPager2) with this code:
yourParentViewPager.isUserInputEnabled = (true or false)
Upvotes: 0
Reputation: 908
I figured out a (slighly hacky) solution while I was typing this question.
It is based on the observation that the state SCROLL_STATE_SETTLING
is only reached when the viewpager really settles on a new page. If there is only fruitless dragging on the first or last page then only the states SCROLL_STATE_DRAGGING
and finally SCROLL_STATE_IDLE
are passed.
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
private boolean settled = false;
@Override
public void onPageScrollStateChanged(int state) {
super.onPageScrollStateChanged(state);
if (state == SCROLL_STATE_DRAGGING) {
settled = false;
}
if (state == SCROLL_STATE_SETTLING) {
settled = true;
}
if (state == SCROLL_STATE_IDLE && !settled) {
doYourOutOfBoundsStuff();
}
}
});
I'm not entirely happy, but this is the best I came across so far.
Upvotes: 7