Does notifydatasetchanged call onCreateViewHolder when using RecyclerView
Asked Answered
P

6

28

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?

Proofread answered 18/2, 2015 at 7:13 Comment(4)
one way to find out is simply put Logs inside onCreateViewHolder and check if they are being called on notifydatasetchanged()... :P is that so hard?Selwin
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 askedProofread
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 thisSelwin
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.Proofread
M
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.

Malaspina answered 26/5, 2015 at 8:51 Comment(2)
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!Tupi
i cant belive this answers save my day :DBosun
W
16

notifyDataSetChanged() calls onBindViewHolder() in case of RecyclerView

Witchy answered 12/5, 2015 at 7:48 Comment(1)
It never calls it for me.Togliatti
D
4

THE SIMPLEST SOLUTION

If you want to refresh RecyclerView items and onCreateView() be called too, say for Grid and List LayoutManagers.

  void refreshRecyclerView(RecyclerView recyclerView){
            Adapter adapterRef=recyclerView.getAdapter();
            recyclerView.setAdapter(null);
            recyclerView.setAdapter(adapterRef);
        }

it will completely refresh the RecyclerView

//example usage
refreshRecyclerView(yourRecyclerView);
Diella answered 25/4, 2021 at 21:53 Comment(1)
By far the simplest solution. I have a Recycler view that adds/deletes various types of items with different view holders in different locations. Refreshing the adapter as this solution states works perfectly. Thank you.Bechtel
T
1

To remove and update layout in RecyclerView, you can call

mRecyclerView.removeView(view);

OR

mRecyclerView.removeViewAt(position);

after removing object in your dataset

Testament answered 7/4, 2015 at 11:36 Comment(0)
S
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" :)

Shir answered 11/9, 2018 at 13:53 Comment(0)
R
-1

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

Ron answered 18/2, 2015 at 7:32 Comment(5)
No, it seems it only calls the onBindViewHolder when the notifydatasetchanged() is called. Thanks for trying to help though.Proofread
No problem thanks well there are always 20 ways to achieve a result you want, its just choosing which one :)Ron
Haha, I would like just one please :PProofread
maybe call setAdapter rather than notifyDataSetChangedRon
haha thanks! Tyring that now.. Also tried calling invalidate() but that did nothingProofread

© 2022 - 2024 — McMap. All rights reserved.