27

I want to use a toggle to toggle between two different views but using the same RecyclerView. Basically, once you toggle, I want the RecyclerView adapter to recall onCreateViewHolder() but this time it will use a different layout item file.

Does notifydatasetchanged() cause the adapter to rebuild itself? Or is there another way?

CopsOnRoad
  • 109,635
  • 30
  • 367
  • 257
AmaJayJB
  • 1,383
  • 2
  • 13
  • 19
  • 1
    one way to find out is simply put `Log`s inside `onCreateViewHolder` and check if they are being called on `notifydatasetchanged()`... `:P` is that so hard? – SMR Feb 18 '15 at 07:21
  • 1
    Fair enough, but i actually want to know what the process is. I tried looking it up. Also that wasn't my only question. Sorry I asked – AmaJayJB Feb 18 '15 at 07:44
  • No worries if you have another question then either edit this question or delete this question and post a new question `:)`. you might wanna read [this](http://stackoverflow.com/help/how-to-ask) – SMR Feb 18 '15 at 07:46
  • 1
    No I am saying in my above post I asked what is another way of doing this. I had a feeling that the notifydatasetchanged() wouldn't do what I wanted. – AmaJayJB Feb 18 '15 at 07:51

6 Answers6

27

I needed to have two types on Views on my RecyclerView Adapter as well, one for 'regular' mode and one for multi-select mode.

So, you can override getItemViewType to force the Adapter to call your onCreateViewHolder for all views.

Add this to the Adapter code:

public void setActionMode(ActionMode actionMode) {
    this.actionMode = actionMode;
    notifyDataSetChanged();
}

@Override
public int getItemViewType(int position) {
    return (actionMode == null ? 0 : 1);
}

Add this to the ViewHolder:

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view;
    if (viewType == 0) {
        view = inflater.inflate(R.layout.layout_1, parent, false);
    } else {
        view = inflater.inflate(R.layout.layout_2, parent, false);
    }
    ...
}

Since you return a different ViewType when in an ActionMode, the Adapter is forced to throw away all created views, and recreate everything again.

marmor
  • 25,207
  • 10
  • 99
  • 145
  • Omg this works. Just by overriding getItemViewType, even though we can technically the actionMode directly in onCreateViewHolder, forces the adapter to call onCreateViewHolder like you said. Thanks! – Bruce Jul 17 '16 at 03:09
  • i cant belive this answers save my day :D – Yudi karma Sep 04 '19 at 10:59
15

notifyDataSetChanged() calls onBindViewHolder() in case of RecyclerView

CopsOnRoad
  • 109,635
  • 30
  • 367
  • 257
Android Developer
  • 7,267
  • 16
  • 62
  • 113
2

To remove and update layout in RecyclerView, you can call

mRecyclerView.removeView(view);

OR

mRecyclerView.removeViewAt(position);

after removing object in your dataset

CopsOnRoad
  • 109,635
  • 30
  • 367
  • 257
streamride
  • 550
  • 4
  • 16
0

Yes it will assume that its current data set is invalid and would need to relayout and rebind all layouts.

Kevin Crain
  • 1,775
  • 16
  • 27
0

I spent more than 6 hours on this issue without any success. Finally!!! I set a global variable in the adapter and had to set it up every time i toggled the view from list to grid (in my case). the funny thing this approauch was there but I forgot to do it as static!! So my solution could be related to yours , just try it and hope it works out.

public static int mCurrentViewType;

then override the getItemType()

  @Override
    public int getItemViewType(int position) {

       return mCurrentViewType;


    }

my toggleItemViewType method:

public void toggleItemViewType () {
        if (mCurrentViewType == LIST_ITEM){
            mCurrentViewType = GRID_ITEM;
        } else {
            mCurrentViewType = LIST_ITEM;
        }
    }

I am accessing the variable from different classes, which is not right, but for now and for the sake of the onCreateViewHolder issue, it worked! if you have a better solution then good luck and share it with us. don't forget to make the global variable as "static" :)

Mujtaba Mahmood
  • 647
  • 1
  • 6
  • 18
0

THE BEST SOLUTION

Why? Because ITEM_VIEW_TYPE is for using completely different views in recyclerview say, a contentView and a bannerAdView

If you want to refresh recyclerview items and onCreateView() be called too say for a Grid and a List ? here is how to do that.

Kotlin

fun refreshRecyclerView(recyclerView:RecyclerView){
     val adapterRef=recyclerView.adapter
     recyclerView.adapter=null
     recyclerView.adapter=adapterRef
     }

Java

void refreshRecyclerView(RecyclerView recyclerView){
        Adapter adapterRef=recyclerView.getAdapter();
        recyclerView.setAdapter(null);
        recyclerView.setAdapter(adapterRef);
        }
Nasib
  • 445
  • 5
  • 15