notifyDataSetChanged not working on RecyclerView

recyclerview notifydatasetchanged not working in fragment
notifydatasetchanged not calling onbindviewholder
notifydatasetchanged not working inside adapter
recyclerview adapter not working
refresh recyclerview after delete item
recyclerview not showing items
notifyitemchanged not working
update recyclerview adapter in fragment

I am getting data from server and then parsing it and storing it in a List. I am using this list for the RecyclerView's adapter. I am using Fragments.

I am using a Nexus 5 with KitKat. I am using support library for this. Will this make a difference?

Here is my code: (Using dummy data for the question)

Member Variables:

List<Business> mBusinesses = new ArrayList<Business>();

RecyclerView recyclerView;
RecyclerView.LayoutManager mLayoutManager;
BusinessAdapter mBusinessAdapter;

My onCreateView():

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    // Getting data from server
    getBusinessesDataFromServer();

    View view = inflater.inflate(R.layout.fragment_business_list,
            container, false);
    recyclerView = (RecyclerView) view
            .findViewById(R.id.business_recycler_view);
    recyclerView.setHasFixedSize(true);

    mLayoutManager = new LinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(mLayoutManager);

    mBusinessAdapter = new BusinessAdapter(mBusinesses);
    recyclerView.setAdapter(mBusinessAdapter);

    return view;
}

After getting data from server, parseResponse() is called.

protected void parseResponse(JSONArray response, String url) {
    // insert dummy data for demo

    mBusinesses.clear();

    Business business;

    business = new Business();
    business.setName("Google");
    business.setDescription("Google HeadQuaters");
    mBusinesses.add(business);

    business = new Business();
    business.setName("Yahoo");
    business.setDescription("Yahoo HeadQuaters");
    mBusinesses.add(business);

    business = new Business();
    business.setName("Microsoft");
    business.setDescription("Microsoft HeadQuaters");
    mBusinesses.add(business);

    Log.d(Const.DEBUG, "Dummy Data Inserted\nBusinesses Length: "
            + mBusinesses.size());

    mBusinessAdapter = new BusinessAdapter(mBusinesses);
    mBusinessAdapter.notifyDataSetChanged();
}

My BusinessAdapter:

public class BusinessAdapter extends
    RecyclerView.Adapter<BusinessAdapter.ViewHolder> {

    private List<Business> mBusinesses = new ArrayList<Business>();

    // Provide a reference to the type of views that you are using
    // (custom viewholder)
    public static class ViewHolder extends RecyclerView.ViewHolder {
        public TextView mTextViewName;
        public TextView mTextViewDescription;
        public ImageView mImageViewLogo;

        public ViewHolder(View v) {
            super(v);
            mTextViewName = (TextView) v
                    .findViewById(R.id.textView_company_name);
            mTextViewDescription = (TextView) v
                    .findViewById(R.id.textView_company_description);
            mImageViewLogo = (ImageView) v
                    .findViewById(R.id.imageView_company_logo);
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public BusinessAdapter(List<Business> myBusinesses) {

        Log.d(Const.DEBUG, "BusinessAdapter -> constructor");

        mBusinesses = myBusinesses;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public BusinessAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
            int viewType) {

        Log.d(Const.DEBUG, "BusinessAdapter -> onCreateViewHolder()");

        // create a new view
        View v = LayoutInflater.from(parent.getContext()).inflate(
                R.layout.item_business_list, parent, false);

        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element

        Log.d(Const.DEBUG, "BusinessAdapter -> onBindViewHolder()");

        Business item = mBusinesses.get(position);
        holder.mTextViewName.setText(item.getName());
        holder.mTextViewDescription.setText(item.getDescription());
        holder.mImageViewLogo.setImageResource(R.drawable.ic_launcher);

    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {

        Log.d(Const.DEBUG, "BusinessAdapter -> getItemCount()");

        if (mBusinesses != null) {
            Log.d(Const.DEBUG, "mBusinesses Count: " + mBusinesses.size());
            return mBusinesses.size();
        }
        return 0;
    }
}

But I don't get the data displayed in the view. What am I doing wrong?

Here is my log,

07-14 21:15:35.669: D/xxx(2259): Dummy Data Inserted
07-14 21:15:35.669: D/xxx(2259): Businesses Length: 3
07-14 21:26:26.969: D/xxx(2732): BusinessAdapter -> constructor

I don't get any logs after this. Shouldn't getItemCount() in adapter should be called again?

notifyDataSetChanged not working on RecyclerView, You either need to: Call recyclerView. setAdapter(mBusinessAdapter) again to update the RecyclerView's adapter reference to point to your new one. Or just remove mBusinessAdapter = new BusinessAdapter(mBusinesses); to continue using the existing adapter. I’m working with Android’s new RecyclerView but I can’t get my custom adapter to refresh whenever I call one of the “notify” methods. I’ve tried calling notifyDataSetChanged, notifyItemRangeInserted and notifyItemInserted and none of them seem to work. Here’s the code for my custom adapter.

Try this method:

List<Business> mBusinesses2 = mBusinesses;
mBusinesses.clear();
mBusinesses.addAll(mBusinesses2);
//and do the notification

a little time consuming, but it should work.

Android RecyclerView Adapter notifyDataSetChanged not working , This can also be an expensive operation, so it is not recommended to use notifyDataSetChanged() if you are only updating a single item or a  Android: NotifyDataSetChanged does not work in RecyclerView.Adapter There is a list of user chats, and the chat data is periodically updated. In service, data is received, and sent to the fragment. When data is received by a fragment, it is sent to the adapter, and the most interesting begins here.

I had same problem. I just solved it with declaring adapter public before onCreate of class.

PostAdapter postAdapter;

after that

postAdapter = new PostAdapter(getActivity(), posts);
recList.setAdapter(postAdapter);

at last I have called:

@Override
protected void onPostExecute(Void aVoid) {
    super.onPostExecute(aVoid);
    // Display the size of your ArrayList
    Log.i("TAG", "Size : " + posts.size());
    progressBar.setVisibility(View.GONE);
    postAdapter.notifyDataSetChanged();
}

May this will helps you.

Updating data in an Android RecyclerView - Suragch, RecyclerView notifyItemRemoved(position) not working properly. I have a RecyclerView with its RecyclerView.Adapter and view holder. I am trying to delete an  One of the main reasons notifyDataSetChanged()won't work for you - is, Your adapter loses reference to your list. When you first initialise the Adapterit takes a reference of your arrayListand passes it to its superclass. But if you reinitialise your existing arrayListit losses the reference, and hence, the communication channel with Adapter.

Just to complement the other answers as I don't think anyone mentioned this here: notifyDataSetChanged() should be executed on the main thread (other notify<Something> methods of RecyclerView.Adapter as well, of course)

From what I gather, since you have the parsing procedures and the call to notifyDataSetChanged() in the same block, either you're calling it from a worker thread, or you're doing JSON parsing on main thread (which is also a no-no as I'm sure you know). So the proper way would be:

protected void parseResponse(JSONArray response, String url) {
    // insert dummy data for demo
    // <yadda yadda yadda>
    mBusinessAdapter = new BusinessAdapter(mBusinesses);
    // or just use recyclerView.post() or [Fragment]getView().post()
    // instead, but make sure views haven't been destroyed while you were
    // parsing
    new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            mBusinessAdapter.notifyDataSetChanged();
        }
    });

}

PS Weird thing is, I don't think you get any indications about the main thread thing from either IDE or run-time logs. This is just from my personal observations: if I do call notifyDataSetChanged() from a worker thread, I don't get the obligatory Only the original thread that created a view hierarchy can touch its views message or anything like that - it just fails silently (and in my case one off-main-thread call can even prevent succeeding main-thread calls from functioning properly, probably because of some kind of race condition)

Moreover, neither the RecyclerView.Adapter api reference nor the relevant official dev guide explicitly mention the main thread requirement at the moment (the moment is 2017) and none of the Android Studio lint inspection rules seem to concern this issue either.

But, here is an explanation of this by the author himself

notifyDataSetChanged not working from within custom adapter , If notifyDataSetChanged() does not trigger view updates than there is a chance that you have forgotten to call SetLayoutManager() on your RecyclerView (like I  Just update your arraylist and invoking to adapter.notifyDataSetChanged(); will make it work.

Although it is a bit strange, but the notifyDataSetChanged does not really work without setting new values to adapter. So, you should do:

array = getNewItems();                    
((MyAdapter) mAdapter).setValues(array);  // pass the new list to adapter !!!
mAdapter.notifyDataSetChanged();       

This has worked for me.

RecyclerView Adapter notifyDataSetChanged not working, Recycler view notifyDataSetChange not working from custom adapter But it is not invoking the method public override int ItemCount. android - tutorial - notifyDataSetChanged not working on RecyclerView recyclerview with image android example (4) Clear your old viewmodel and set the new data to the adapter and call notifyDataSetChanged () I am getting data from server and then parsing it and storing it in a List.

Recycler view notifyDataSetChange not working from custom , Recyclerview items have a button for add to cart and remove from cart The problems is that if user add an item to cart is not Visible Remove  you are setting the new list to the RecyclerView Adapter , set the list in the Adapter: make a method setItems(list) in adapter and call it before notifyDataSetChanged() and in adapter do . this.persons = new ArrayList<>(persons); in setItems. add this method in adapter: public void setItems(List<ServiceModel> persons) { this.persons = persons; }

Recycleviewer Adapter NotifyDataSetChanged not work , adapter.notifydatasetchanged() not working in kotlin recyclerview adapter notifydatasetchanged not working in fragment arrayadapter notifydatasetchanged not  Use the notifyDataSetChanged() every time the list is updated. To call it on the UI-Thread, use the runOnUiThread() of Activity. Then, notifyDataSetChanged() will work. Multiple choice in listView You need: Interface Data (String text, boolean selected) Adapter Fragment or Activity (calling notifyDataSetChanged custom adapter) list_item.xml

adapter.notifyDataSetChange() doesnt work, The RecyclerView Adapter code can be found at this answer. MainActivity.java. This can also be an expensive operation, so it is not recommended to use notifyDataSetChanged()

Comments
  • Thanks for your help!!! Got it.. just removed the line that creates a new instance again. Will accept your answer in 8 mins.
  • This did not work for me, i had to recrate teh adapter and set it again to the recylerview
  • I'm following your second point by creating the adapter again with new BusinessAdapter(mBusinesses). Do I have to release the old adapter in any way? Will this cause a memory leak if I just keep creating a new adapter each time?
  • As long as you are not statically referencing anything or otherwise holding on to references, you can just let the old reference go.
  • Just find position where you added or removed data from your list using int index = list.indexOf(object) and according to that index you can notify data using adapter.notifyItemChanged(index)
  • This statement: List<Business> mBusinesses2 = mBusinesses; does not make a deep copy of the list. So you're not cloning the list - that's one thing, the second thing is I don't see how this could solve the original problem....
  • Actually I had a similar problem and resolved it this way: solution
  • @kosiara-BartoszKosarzycki Yet it does
  • Man thanks a lot! Out of all things I tried, yours worked flawlessly.
  • @Maximus glad I could help, mate