RecyclerView Adapter notifyDataSetChanged not working
Asked Answered
B

8

32

I extended

RecyclerView.Adapter<RecyclerView.ViewHolder>

And when I called:

mRecyclerView.getAdapter().notifyDataSetChanged();

Nothing happened.

The only way to refresh the view is to set again the adapter (see this answer):

mRecyclerView.setAdapter(new MyAdapter(...));

I have two issues with this solution:

  1. I can see a blink on the screen when I set again the adapter
  2. The listview returns to the first position.

Any ideas?

Boost answered 30/12, 2014 at 23:32 Comment(6)
Have you tried to encapsulate notifyDataSetChanged method in MyAdapter? Eg: Create "myNotifyDataSetChanged" in MyAdapter and from that method call this.notifyDataSetChanged()". Save MyAdapter reference and call myAdapterRef.myNotifyDataSetChanged() instead of myRecyiclerView.getAdapter().notifyDataSetChanged(). Sont know why it worked for me (i had that problem with ListView)Pendley
@helionprime Didn't help :(Boost
ok, my bad. I forgot to get/use the updated Data within the onBindViewHolder method. But what about the blink effect, how can I get rid of it?Boost
ok, my bad2. The blink effect related to load image into the imageViews within my items. It's a known issue of UniversalImageLoader (github.com/nostra13/Android-Universal-Image-Loader/issues/376) that I'm using.Boost
I am glad you've managed to solve it :-). If you want to try to get rid of fliickering, on this link github.com/bajicdusko/AndroidJsonProvider/tree/master/app/src/… you can try Image loader i have developed for myself. It also supports caching, optimizing, autodownload and showing default image in case of errors.Pendley
Were u able to find the solution of your problem@David. I have the same problem.Emunctory
B
37

If notifyDataSetChanged() does not trigger view updates than there is a chance that you have forgotten to call SetLayoutManager() on your RecyclerView (like I did!). Just don't forget to do this: Java code:

LinearLayoutManager layoutManager = new LinearLayoutManager(context ,LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(layoutManager)

C# code, I'm using Xamarin.

var layoutManager = new LinearLayoutManager(Context, LinearLayoutManager.Vertical, false);
recyclerView.SetLayoutManager(layoutManager);

before you call recyclerView.SetAdapter(adapter);

If you prefer declaring it in xml, so you cannot forget it in the code you can also add these lines to the xml of your recyclerView:

app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
android:orientation="vertical"
Barnstorm answered 24/10, 2016 at 14:0 Comment(0)
I
28

If your getItemCount() returns 0, then notifyDataSetChanged() won't do anything. Make sure that when you initialize your adapter, you are passing a valid dataset.

Iodism answered 14/10, 2015 at 22:11 Comment(0)
F
4

According to the javadocs: If you are writing an adapter it will always be more efficient to use the more specific change events if you can. Rely on notifyDataSetChanged() as a last resort.

public class NewsAdapter extends RecyclerView.Adapter<...> {    

private static List mFeedsList;
...

    public void swap(List list){
    if (mFeedsList != null) {
        mFeedsList.clear();
        mFeedsList.addAll(list);
    }
    else {
        mFeedsList = list;
    }
    notifyDataSetChanged();
}

I am using Retrofit to fetch the list, on Retrofit's onResponse() use,

adapter.swap(feedList);
Fake answered 24/12, 2015 at 6:41 Comment(2)
"According to the javadocs: If you are writing an adapter it will always be more efficient to use the more specific change events if you can" where in javadocs did you find this info?Lacagnia
developer.android.com/reference/android/support/v7/widget/…Fake
W
4

To update recyclerview we can do the following:

  1. Create and set adapter again:

    adapter=new MyAdapter(...);
    mRecyclerView.setAdapter(adapter);
    
  2. Clear model list data and then notify:

    List<YourModel> tempModel=new ArrayList<>(modelList); 
    modelList.clear();   
    modelList.addAll(tempModel); 
    adapter.notifyDataSetChanged();
    
Westberry answered 2/2, 2018 at 13:21 Comment(1)
There is no need to create a new adapter every time. All you need is to pass a new data to the existing adapter. Please, see my working example below.Stay
S
4

In my case, nothing but this has worked. When it's time to refresh a RecyclerView, I did:

array = getNewItems();                    // populates the list with new items
((MyAdapter) mAdapter).setValues(array);  // pass the new list to adapter !!!
mAdapter.notifyDataSetChanged();          // tell the adapter a data set has changed

In the MyAdapter, I put the setter for data:

public void setValues(List<Item> items){
    this.items = items;
}

That's it!

[Notice that the notifyDataSetChanged does not work without setting new values to adapter.]

Stay answered 15/10, 2019 at 13:30 Comment(0)
G
0

Want to share something, I was facing the same issue. But what i was doing wrong was. I was creating instance of Adapter every time new and than doing notifysetDatachange() to that new instance not the older one.

So please make sure Adapter whom you notifysetDatachange() should be older one. Hope below example helps..

     MyAdapter mAdapter = new MyAdapter(...)

    mRecyclerView.setAdapter(mAdapter );

// TODO 
mAdapter.modifyData(....);
mAdapter.notifySetDataChange();


    MyAdapter extends baseAdapter {
     MyAdapter () {
    }
    modifyData(String[] listData) {

    }

    }
Giarla answered 13/1, 2017 at 21:39 Comment(0)
L
0

notifyDataSetChanged() sholud be called in main thread.

Larianna answered 8/2, 2017 at 7:31 Comment(2)
This does not seem to be the problemNiu
Thank you. My problem was listener in service, which run on other thread.Lenticel
S
0

So i fixed my problem like this : orderList is the List that i pass on to the recyclerview . We can just add the item at the position in the list, here 0 is the 0th position in the List . Then call adapter.notifyDataSetChanged() . Works like a charm

1) orderList.add(0,String); 2) orderAdapter.notifyDataSetChanged();

Squander answered 28/8, 2018 at 11:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.