The issue I'm noticing happens when the user scrolls to the next (or previous) page in the ViewPager, which triggers the ViewPager's settling (confirm?) to that page. This works perfectly unless the user starts dragging while the ViewPager is still settling. In this scenario what I get is the title shown by the TitlePageIndicator shows the title for 2 pages after (or before, respectively) while the content shown by the ViewPager is showing the next (or previous) page.
If the user starts to swipe after that page - the one with the mismatched title and content - has settled, the title gets quickly updated to the correct title. Looking at ViewPager.OnPageChangeListener they say "Useful for discovering when the user begins dragging, when the pager is automatically settling to the current page" for onPageScrollStateChanged(int), which seems to be what the issue is, but I haven't found a way to use the method to resolve the issue.
I'm using Jake Wharton's com.viewpagerindicator.TitlePageIndicator with android.support.v4.view.ViewPager to render a view of calendar days. Swiping left/right moves to the previous/next calendar day. This means my ViewPager is set up to implement infinite pagination based on 3 Fragments that correspond to the visible day, the day before the visible day, and the day after the visible day.
My ViewPager.OnPageChangeListener is constructed like this and attached to the TitlePageIndicator
_title.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
private int _focused_page = _VISIBLE;
private boolean _is_settling = false;
@Override
public void onPageScrollStateChanged(int state) {
if (state == ViewPager.SCROLL_STATE_IDLE) {
if (_focused_page == _PREVIOUS)
moveToPrevious();
else if (_focused_page == _NEXT)
moveToNext();
// always set to middle page to continue to be able to
// scroll left/right
if (_paginator.getCurrentItem() != _VISIBLE)
_paginator.setCurrentItem(_VISIBLE, false);
_is_settling = false;
} else if (state == ViewPager.SCROLL_STATE_DRAGGING && _is_settling) {
Ln.d("Double scrolled!");
_title.setCurrentItem(_paginator.getCurrentItem());
_title.invalidate();
} else if (state == ViewPager.SCROLL_STATE_SETTLING) {
_is_settling = true;
}
}
@Override
public void onPageSelected(int position) {
_focused_page = position;
}
});
I see there to be about 3 solutions
- Disable the sending or responding to user drag event while settling
- Notice when the drag occurs during a settling and recover the correct title after it becomes invalid
- Move the
ViewPagerwith the second drag as if it were the first drag resulting in everything being 2 pages after (or before) the original visible day
EDIT:
Is there a way to force the TitlePageIndicator to call getPageTitle(int) again to redraw the title with the correct title?