My RecyclerView contains many ViewPagers. The number of pages inside each ViewPager is constant (2). I use PagerAdapter.
When I scroll my RecyclerView, the ViewPagers lose their state and reset to the 1st page. I want to know how to retain the last selected page for each ViewPager.
For example: 1) I scroll to page 2 in my 1st ViewPager 2) I scroll the RecyclerView to the bottom and my 1st ViewPager goes out of screen. 3) I scroll to the top of the ViewPager and so my 1st ViewPager loads again. 4) My 1st ViewPager is set to 1st page instead of page 2 which I lastly scrolled to.
There are 'n' number of ViewPagers inside the RecyclerView and I want to retain all their states regardless of reloading due to RecyclerView.
How to solve this logic?
Well, I wrote little bit brute-force solution for this.
My PagerAdapter
:
public class ViewPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return 2;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
FrameLayout layout = new FrameLayout(container.getContext());
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
layout.setLayoutParams(layoutParams);
layout.setBackgroundColor(position % 2 == 0 ? Color.RED : Color.BLUE);
container.addView(layout);
return layout;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
super.destroyItem(container, position, object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
(so we the visually "state" differs in it's color - it's red in first position and blue in the second position)
The RecyclerViewAdapter
looks like:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
public HashMap<Integer, Integer> viewPageStates = new HashMap<>();
public RecyclerViewAdapter() {}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
return new ViewHolder(new ViewWithViewPager(viewGroup.getContext()));
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((ViewWithViewPager) holder.itemView).refreshState(position, viewPageStates.containsKey(position)? viewPageStates.get(position) : 0);
}
@Override
public int getItemCount() {
return 42;
}
@Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
ViewWithViewPager recycledViewPager = ((ViewWithViewPager)holder.itemView);
viewPageStates.put(recycledViewPager.viewPosition, recycledViewPager.viewPager.getCurrentItem());
super.onViewRecycled(holder);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View itemView) {
super(itemView);
}
}
}
I.e. every time we bind RecyclerView
's ViewHolder
, we pass the current state of the viewpager(from viewPageStates
) and its order in RecyclerView
's dataset.
Once it's recycled - we read its current page state and saving it into HashMap
viewPageStates
.
The last piece - the ViewWithViewPager
public class ViewWithViewPager extends FrameLayout {
ViewPager viewPager;
int viewPosition = 0;
public ViewWithViewPager(Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.item_layout, this);
viewPager = (ViewPager) findViewById(R.id.viewPager);
viewPager.setAdapter(new ViewPagerAdapter());
}
public void refreshState(int position, int selectedPage) {
viewPosition = position;
viewPager.setCurrentItem(selectedPage);
}
}
I.e. in refreshState
we set ViewPager to the proper page
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With