简体   繁体   中英

Scroll ViewPager's RecyclerView when page gets scrolled

I have a ViewPager with a couple of RecyclerViews as pages. I would like to implement functionality where RecyclerViews which are on other pages move by certain amount after user starts scrolling pages.

@Override
public void onPageScrolled(int position, float offset, int offsetPx) {
    RecyclerView view1 = getPage(position - 1);
    RecyclerView view2 = getPage(position + 1);

    if(scrollNeeded()) {
      view1.scrollBy(0, 200);
      view2.scrollBy(0, 200);
    }
}

The problem which I have is that everything works fine if I scroll slowly through my ViewPager but if I scroll crazy fast, some RecyclerViews don't get scrolled. I guess I somehow need to synchronize this method.

Any idea how to solve this problem? User shouldn't see that scroll.

ViewPager keeps +1 page left and right preloaded. Which means

  • in very beginning - current page and the next one
  • at the very end - last page and the previous one
  • anywhere else - current, previous and next

When user swipes really fast through pages, there is a real case where the page (your RecyclerView instance and its adapter) are still preparing, so they miss the scrollBy() call.

You can solve this in different ways.

  1. Easiest is increasing the number of cached off screen pages (eg 3) by calling viewPager.setOffscreenPageLimit(3) - for more ViewPager.setOffScreenPageLimit(int) . If you rely on page refreshes every time user swipes, this might be an issue.

  2. Another option is creating a custom view for your RecyclerView page and adding a scroll value to be set from outside, eg

     // in your custom page view private RecyclerView.Adapter adapter; private boolean needToScroll; public void setNeedToScroll(boolean needToScroll) { this.needToScroll = needToScroll; // if adapter is not null (ie already set), scroll as is // and set the value to false if (adapter != null) { this.needToScroll = false; scrollBy(0, 200); } } // and then in the place where you define your adapter, but after setting it if (needToScroll) { needToScroll = false; scrollBy(0, 200); } 

    Finally your view pager scroll listener

     @Override public void onPageScrolled(int position, float offset, int offsetPx) { if(scrollNeeded()) { Page view1 = getPage(position - 1); Page view2 = getPage(position + 1); view1.needToScroll(true); view2.needToScroll(true); } } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM