How to update RecyclerView adapter using DiffUtil

Viewed 3315

Im used to create a new Adapter and an new RecycleView every time I needed to update the alarms that in the RecycleView. unfortunately it just a very expensive "solution". I saw online that I can use DiffUti, but Im not sure how to implement it. I created a DiffUtil class:

public class AlarmDiffCallBack extends DiffUtil.Callback{
private final ArrayList<SingleAlarm> oldList;
private final  ArrayList<SingleAlarm> newList;

public AlarmDiffCallBack( ArrayList<SingleAlarm> oldList, ArrayList<SingleAlarm> newList) {
    this.oldList = oldList;
    this.newList = newList;
}

@Override
public int getOldListSize() {
    return oldList.size();
}

@Override
public int getNewListSize() {
    return newList.size();
}

@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
    return oldList.get(oldItemPosition).getAlarmIndex() == newList.get(newItemPosition).getAlarmIndex();
}

@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
    return oldList.get(oldItemPosition).getAlarmIndex() == newList.get(newItemPosition).getAlarmIndex();
}

@Nullable
@Override
public Object getChangePayload(int oldItemPosition, int newItemPosition) {
    // Implement method if you're going to use ItemAnimator
    return super.getChangePayload(oldItemPosition, newItemPosition);
}

}

and this is one of the places I want to update the recycleView in(replace the "creatAdapter" with the DiffUtil):

 public void add_alarm(final Context context) {
    //creating a new alarm and set the relevant varible to the addAlarm function
    button_add_alarm.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            //the calndar is without the right day, the day is added in the handler(int the loop)
            Calendar calendarForAlarm = timePickerToCalendar(alarmTimePicker);
            alarmsList = alarmHandler.add_alarm(context, checkBoxes, alarmMessage, alarmsList, alarm_manager, calendarForAlarm, repeatAlarm);
            alarmsList=alarmHandler.sortAlarms(alarmsList);
            creatAdapt();
        }
    });
}

I just cant figure out how to use this class to update my Adapter. Im pretty new to android and programming in general, hope this quotation is OK. Thanks!

2 Answers

So basically you need your adapter to have a method to update your data, like that:

public void setNewAlarms(List<SingleAlarm> newAlarms){
    // oldAlarms is the list of items currently displayed by the adapter
    AlarmDiffCallBack diffCallBack = new AlarmDiffCallBack(oldAlarms, newAlarms);

    // Second parameter is to detect "movement". If your list is always sorted the same way, you can set it to false to optimize
    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallBack, true);

    // This will notify the adapter of what is new data, and will animate/update it for you ("this" being the adapter)
    diffResult.dispatchUpdatesTo(this);
}

And then you just have to call myAdapater.setNewAlarms(alarmsList) from outside the adapter, with the new data.

You can also take a look at the following repository that implements it

Your areItemsTheSame and areContentsTheSame methods are the same.

getChangePayload only gets triggered if areItemsTheSame returns true and areContentsTheSame returns false, so I think it'll never trigger

Related