Search code examples
javaandroidandroid-fragmentsadapternotifydatasetchanged

notifyDataSetChanged not working with fragments


i have a data storage two fragments and adapter, main idea is:

  1. fragment 1 onResume() ask for new data
  2. data is loaded and added to data storage
  3. broadcast sends a message REST_UPDATE_ITEMS
  4. fragment 1 catch that message and update items in adapter

what is going on: I open fragment 1 - it's ok, new data is uploaded, new adapter is created and added to RecyclerView and I see items in list

when i go to fragment 2 and then go back to fragment 1 - new data is uploaded and fragment 1 catches new message, but list is empty

so: this is method that catches message

case REST_UPDATE_ITEMS: {
    if (adapter == null) {
        adapter = new MyAdapter(getActivity(), DataStorage.getInstance().getItems());
        recyclerView.setAdapter(adapter);
    } else {
        adapter.swap(DataStorage.getInstance().getItems());
        getActivity().runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    adapter.notifyDataSetChanged();
                                }
                            });
     }
     break;
}

and nothing happens when notifyDataSetChanged() is called, just empty list, but if i will only create new adapter each time

case REST_UPDATE_ITEMS: {
            adapter = new MyAdapter(getActivity(), DataStorage.getInstance().getItems());
            recyclerView.setAdapter(adapter);
         break;
    }

it works and updating data every time, but it blinks! every time i see this annoying blinks.

I want smooth data replacement, or just not empty list every time when i open fragment: old data -> some fancy effect -> new data

But every time when i open fragment : empty -> blink or even fancy effect -> some data

and this is swap method from adapter:

public void swap(ArrayList<Items> items){
    this.items.clear();
    this.items.addAll(items);
}

fragments created when activity starts and then just

getFragmentManager().beginTransaction().add(R.id.frame_layout,fragment2).commit();

to open fragment 2 and

getFragmentManager().beginTransaction().replace(R.id.frame_layout, fragment1).commit();

to go back to fragment 1


Solution

  • ok, this is weird, but I found solution in my layout RecyclerView was child of ScrollView - i removed ScrollView and changed update method like this:

    case REST_UPDATE: {
        if (adapter == null || recyclerView.getAdapter() == null) {
            adapter = new adapter(getActivity(), DataStorage.getInstance().getItems());
            recyclerView.setAdapter(adapter);
        } else {
            adapter.swap(DataStorage.getInstance().getItems());
        }
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                adapter.notifyDataSetChanged();
            }
        });
        break;
    }
    

    and now it working, i still don't understand, can someone explain what was happening?