Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement viewpager in recyclerview

I want to create ViewPager (holder) in RecyclerView when I create it and scroll view pager some row then I scroll RecyclerViewand some element that reuse component.

My Code:

MainActivity

public class MainActivity extends AppCompatActivity {
    private RecyclerView rcv;
    private LinearLayoutManager llom;
    private MainActivityAdapter adapter;
    private List<String> list1 = new ArrayList<>();
    private List<String> list2 = new ArrayList<>();
    private List<String> list3 = new ArrayList<>();
    private List<String> list4 = new ArrayList<>();
    private List<String> list5 = new ArrayList<>();
    private List<String> list6 = new ArrayList<>();
    private List<String> list7 = new ArrayList<>();
    private List<String> list8 = new ArrayList<>();
    private List<String> list9 = new ArrayList<>();
    private List<String> list10 = new ArrayList<>();
    private HashMap<Integer, List<String>> hashMap = new HashMap<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        list1.add("1");
        list1.add("2");
        list1.add("3");
        list1.add("4");
        list1.add("5");

        list2.add("1");
        list2.add("2");
        list2.add("3");
        list2.add("4");
        list2.add("5");

        list3.add("1");
        list3.add("2");
        list3.add("3");
        list3.add("4");
        list3.add("5");

        list4.add("1");
        list4.add("2");
        list4.add("3");
        list4.add("4");
        list4.add("5");

        list5.add("1");
        list5.add("2");
        list5.add("3");
        list5.add("4");
        list5.add("5");

        list6.add("1");
        list6.add("2");
        list6.add("3");
        list6.add("4");
        list6.add("5");

        list7.add("1");
        list7.add("2");
        list7.add("3");
        list7.add("4");
        list7.add("5");

        list8.add("1");
        list8.add("2");
        list8.add("3");
        list8.add("4");
        list8.add("5");

        list9.add("1");
        list9.add("2");
        list9.add("3");
        list9.add("4");
        list9.add("5");

        list10.add("1");
        list10.add("2");
        list10.add("3");
        list10.add("4");
        list10.add("5");

        hashMap.put(0,list1);
        hashMap.put(1,list2);
        hashMap.put(2,list3);
        hashMap.put(3,list4);
        hashMap.put(4,list5);
        hashMap.put(5,list6);
        hashMap.put(6,list7);
        hashMap.put(7,list8);
        hashMap.put(8,list9);
        hashMap.put(9,list10);

        rcv = (RecyclerView) findViewById(R.id.rcv);
        llom = new LinearLayoutManager(this);
        rcv.setLayoutManager(llom);
        adapter = new MainActivityAdapter(this, hashMap);
        rcv.setAdapter(adapter);

    }
}

MainActivityAdapter

public class MainActivityAdapter extends RecyclerView.Adapter {
    private Context context;
    private static final int TEST = 0;
    private HashMap<Integer, List<String>> hashMap;

    public MainActivityAdapter(Context context, HashMap<Integer, List<String>> hashMap) {
        this.context = context;
        this.hashMap = hashMap;

    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new VpListItem(new ViewPagerListItem(context));


    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        ((VpListItem) holder).fillData(hashMap.get(position), position);

    }

    @Override
    public int getItemCount() {
        return hashMap.size();
    }


    public static class VpListItem extends RecyclerView.ViewHolder {
        private ViewPagerListItem otherArticlesListItem;

        public VpListItem(ViewPagerListItem itemView) {
            super(itemView);
            this.otherArticlesListItem = itemView;
        }

        public void fillData(List<String> list, int position) {
            otherArticlesListItem.fillData(list, position);

        }


    }
}

ViewPagerListItem

public class ViewPagerListItem extends RelativeLayout {
    private Context context;
    private WrapContentViewPager vp;
    private ViewPagerAdapter adapter;
    private List<String> list = new ArrayList<>();


    public ViewPagerListItem(Context context) {
        super(context);
        this.context = context;
        setupView();
    }

    public ViewPagerListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        setupView();
    }

    public ViewPagerListItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        setupView();
    }

    private void setupView() {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.vp_list_item, this, true);
        vp = (WrapContentViewPager) view.findViewById(R.id.vp);
        adapter = new ViewPagerAdapter(context, list);
        vp.setAdapter(adapter);


    }

    public void fillData(List<String> list, int id) {
        vp.setId(id);
        this.list.addAll(list);
        adapter.notifyDataSetChanged();


    }
}

ViewPagerAdapter

public class ViewPagerAdapter extends PagerAdapter {
    private Context context;
    private List<String> list;


    public ViewPagerAdapter(Context context, List<String> list) {
        this.context = context;
        this.list = list;


    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public int getItemPosition(Object object) {
        return POSITION_NONE;
    }

    @Override
    public boolean isViewFromObject(View view, Object object) {
        return view == (View) object;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) {
        container.removeView((View) object);
    }

    @Override
    public Object instantiateItem(ViewGroup container, final int position) {

        CardListItem cardListItem = new CardListItem(context);
        cardListItem.fillData(list.get(position));
        container.addView(cardListItem);
        return cardListItem;
    }
}


CardListItem

    public class CardListItem extends LinearLayout {
    private Context context;
    private TextView tv;

    public CardListItem(Context context) {
        super(context);
        this.context = context;
        setupView();
    }

    public CardListItem(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        setupView();
    }

    public CardListItem(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
        setupView();
    }

    private void setupView() {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.card_list_item, this, true);
        tv = (TextView) view.findViewById(R.id.tv);


    }

    public void fillData(String text) {
        tv.setText(text);


    }
}

Then I scroll RecyclerView some time it lag . And I scroll ViewPager then I scroll RecyclerView some element (ViewPager that not scroll) change according to ViewPager that I scroll

Thank you.

like image 419
Wuttipong Khemphetjetsada Avatar asked Sep 20 '16 06:09

Wuttipong Khemphetjetsada


People also ask

Does ViewPager use RecyclerView?

ViewPager2 comes with right-to-left support, orientation changes, now you can use RecyclerView with ViewPager which can enable usage of DiffUtils, LayoutManager, PageTransformations, Fragments as pages which are modifiable etc.

How the ViewPager is implemented?

Implement Swipe Views You can create swipe views using AndroidX's ViewPager widget. To use ViewPager and tabs, you need to add a dependency on ViewPager and on Material Components to your project. To insert child views that represent each page, you need to hook this layout to a PagerAdapter .


1 Answers

I've created sample project in which there is recycler view two types of items:

  1. Simple Text View
  2. View Pager

You can check it here

Inflation of these view is done in Adapter View:

 @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

    RecyclerView.ViewHolder viewHolder = null;
    LayoutInflater inflater = LayoutInflater.from(parent.getContext());

    switch (viewType) {

        case VIEW_TYPE_TEXT:
            View userView = inflater.inflate(R.layout.item_recycler_text, parent, false);
            viewHolder = new TextItemHolder(userView);
            break;

        case VIEW_TYPE_PAGER:
            View blockbusterView = inflater.inflate(R.layout.item_recycler_pager, parent, false);
            viewHolder = new PagerItemHolder(blockbusterView);
            break;
    }

    return viewHolder;
}

@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

    switch (holder.getItemViewType()) {

        case VIEW_TYPE_TEXT:
            TextItemHolder textHolder = (TextItemHolder) holder;
            configureTextItem(textHolder, position);
            break;

        case VIEW_TYPE_PAGER:
            PagerItemHolder pagerHolder = (PagerItemHolder) holder;
            configurePagerHolder(pagerHolder, position);
            break;
    }
}

private void configureTextItem(TextItemHolder holder, int position) {

    Data data = mDataList.get(position);

    if (!Check.isEmpty(data.getTextItem()))
        holder.tvTitle.setText(data.getTextItem());
}

private void configurePagerHolder(PagerItemHolder holder, int position) {

    Data data = mDataList.get(position);

    CustomPagerAdapter adapter = new CustomPagerAdapter(data.getPagerItemList(), mContext);
    holder.viewPager.setAdapter(adapter);
}

Hope it helps.. !!

Edited:

For restoring previously scrolled state in ViewPager, when an item in Recycler View we have to:

  1. Override onViewRecycled method of RecyclerView.Adapter
  2. Maintain a hash for previous position scrolled to. And values can be called as:

if (mViewPageStates.containsKey(position)) holder.viewPager.setCurrentItem(mViewPageStates.get(position));

like image 164
Harneev Avatar answered Oct 11 '22 16:10

Harneev