Search code examples
androidandroid-recyclerviewnotifydatasetchanged

notifyDataSetChanged() not working on custom RecyclerView adapter


I was trying to create a recyclerView that shows a list of current statusbar notifications . I have created a custom adapter (NotiRecyclerAdapter) that takes a List of NotificationItemInformation

public class NotificationItemInformation
{
  int iconId,noitId;
  String packageName;
  Drawable notiIcon;
}

I am using an SQLite DB to store all the notifications. The NotificationListenerService writes and deletes from the DB whenever a notification is posted or removed.

I use a method called

public List<NotificationItemInformation> ReadNotilist (Context context);

( which is inside myDBHelper ) to read the contents of the DB to a List of NotificationItemInformation called data (which is global,public and static in my Main Activity ) . then I use adapter (which is also global,public and static in my Main Activity ) to take the data and set it to the RecyclerView inside the onCreate method of my MainActivity.

So far everything is working well. and i can see the RecyclerView populated with the current StatusBar notification.

The problem is that the list does not update (if a new notification comes) till i restart the activity . I tried calling...

MainActivity.data.clear();
MainActivity.data = dbh.ReadNotilist(this); // dbh is DBhelper object
MainActivity.adapter.notifyDataSetChanged();

...inside onNotificationPosted (after the adding into DB) of my NotificationListenerService . But still the RecyclerView is not getting updated till I restart the activity.

Here is my MainActivity if you want to take a look.

public class MainActivity extends AppCompatActivity
{

    SQLiteDatabase db;
    DBHelper dbh;

    RecyclerView notificationIconRecyclerView;
    public static NotiRecyclerAdapter adapter;
    public static List<NotificationItemInformation> data = Collections.EMPTY_LIST;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        dbh = new DBHelper(this);
        db = dbh.getDb();
        notificationIconRecyclerView = (RecyclerView) findViewById(R.id.notificationIconRecyclerView);
        data = dbh.ReadNotilist(this);
        adapter = new NotiRecyclerAdapter(this,data);
        notificationIconRecyclerView.setAdapter(adapter);
        notificationIconRecyclerView.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.HORIZONTAL,true));
    }
}

Here is my custom Adapter for the RecyclerView

public class NotiRecyclerAdapter extends RecyclerView.Adapter<NotiRecyclerAdapter.MyViewHolder>
{

    private LayoutInflater inflater;
    List<NotificationItemInformation> data = Collections.emptyList();

    NotiRecyclerAdapter(Context context, List<NotificationItemInformation> data)
    {
        inflater = LayoutInflater.from(context);
        this.data = data;
    }


    @Override
    public void registerAdapterDataObserver(RecyclerView.AdapterDataObserver observer)
    {
        super.registerAdapterDataObserver(observer);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
    {
        View view = inflater.inflate(R.layout.custom_recyclerview_item,parent,false);
        MyViewHolder holder = new MyViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position)
    {
        NotificationItemInformation current = data.get(position);
        holder.recyclerItemIcon.setImageDrawable(current.notiIcon);
    }

    @Override
    public int getItemCount()
    {
        return data.size();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder
    {
        ImageView recyclerItemIcon;
        public MyViewHolder(View itemView)
        {
            super(itemView);
            recyclerItemIcon = itemView.findViewById(R.id.notiRecyclerItemIcon);
        }
    }

}

Solution

  • Do not reset the reference to the data object. Instead try something like this:

    MainActivity.data.clear();
    MainActivity.data.addAll(dbh.ReadNotilist(this));
    MainActivity.adapter.notifyDataSetChanged();