简体   繁体   中英

How to resume ViewPager2 from the same position when the fragment containing it was stopped and resumed later?

I have a ViewPager2 which is a horizontal ImageView scroller which is autoscrolling enabled. This autoscrolling is implemented using Timer.schedule().

The issue that I am struggling to solve is I want this autoscroll to stop right there when the fragment containing that is no longer visible to the User, and once the User resumes this fragment, the ViewPager should start autoscrolling from the same position where it was left.

My code for ViewPager:

public class ChannelPagerViewHolder extends RecyclerView.ViewHolder {
    private static final int LIMIT = 7;
    private static final @ViewPager2.OffscreenPageLimit int OFFSCREEN_PAGE_LIMIT = 2;

    private Context mContext;
    private LifecycleOwner mLifecycleOwner;
    private ViewPager2 viewPager;
    private LiveData<List<ChannelItem>> mChannelItemList;
    private BannerAdapter bannerAdapter;
    private Handler mHandler;
    private int currentPage;
    private int prevPageNumber;

    public ChannelPagerViewHolder(View view, Context context, LifecycleOwner lifecycleOwner, int placement) {
        super(view);
        Log.d("ChannelPagerViewHolder","");
        mContext = context;
        mLifecycleOwner = lifecycleOwner;
        viewPager = view.findViewById(R.id.view_pager);
        viewPager.setOffscreenPageLimit(OFFSCREEN_PAGE_LIMIT);

        viewPager.getLayoutParams().width =
                (int) (Resources.getSystem().getDisplayMetrics().widthPixels);
        viewPager.getLayoutParams().height =
                viewPager.getLayoutParams().width / 2;
        bannerAdapter = new BannerAdapter(mContext, placement);
        viewPager.setAdapter(bannerAdapter);
        viewPager.setClipToPadding(false);
        viewPager.setPadding(24,0,24,0);

        // Hack to make left and right banner visible.
        RecyclerView recyclerView = ((RecyclerView) viewPager.getChildAt(0));
        recyclerView.setClipToPadding(false);
        UserEventLogger.getInstance(context).addImpressionLogger(
                recyclerView,
                placement
        );

        mHandler = new Handler();
        currentPage = 0;
        viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
                currentPage = position;
                prevPageNumber = currentPage;
            }
        });



        new Timer().schedule(
                new TimerTask() {
                    @Override
                    public void run() {
                        mHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                viewPager.setCurrentItem(currentPage++);
                            }
                        });
                    }
                },
                1000,
                1000
        );
    }
}

UI of ViewPager: My ViewPager

Any help would be appreciated!!

Since you are using ViewPager inside a RecyclerView's ViewHolder, you need to store the currentPosition of the ViewPager for that particular item somewhere and restore it when rebinding that item.

My solution would be to use a mutable field inside the class that represents your recycler view's Item and set it to a new position each time ViewPager 's page changes, Then restore it when you are rebounding that item to a ViewHolder .

Your Item class can be something like this:

class Item {
    List<Page> pages;
    int currentPage = 0;
}

Then inside your ViewHolder

public class ChannelPagerViewHolder extends RecyclerView.ViewHolder {

    // ...

    void bind(Item item) {
        // ...

        viewPager.setCurrentItem(item.currentPosition)

        viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels);
                // ..
                item.currentPosition = position
            }
        });

        // ...
    }
}

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