如何使用DiffUtil更新RecyclerView适配器

4

我习惯于每次需要更新RecycleView中的闹钟时都创建一个新的Adapter和一个新的RecycleView。不幸的是,这只是一种非常昂贵的“解决方案”。我在网上看到可以使用DiffUtil,但我不确定如何实现它。我创建了一个DiffUtil类:

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);
}

这是我想要更新 RecyclerView 的其中一个位置(使用 DiffUtil 替换 "creatAdapter"):

 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();
        }
    });
}

我只是不知道如何使用这个类来更新我的Adapter。我对安卓和编程一般都很新,希望这句引言没问题。谢谢!

2个回答

2
所以基本上你需要让你的适配器有一个更新数据的方法,像这样:
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);
}

然后,您只需从适配器外部调用myAdapater.setNewAlarms(alarmsList),并使用新数据。

您还可以查看以下存储库进行实现


你帮我更接近解决方案了,但它仍然对我无效。首先,我看到在你的存储库中,你手动更新列表(list.clear(); list.addall(); - 即使我操作diffResult.dispatchUpdatesTo(this),我是否应该添加这些列表?) 此外,使用这些函数或不使用,我的RecyclerView都没有更新,也许是我的AlarmDiffCallBack出了问题? 非常感谢! - Nakash.i

0

你的areItemsTheSameareContentsTheSame方法是一样的。

只有当areItemsTheSame返回true且areContentsTheSame返回false时,getChangePayload才会被触发,所以我认为它永远不会被触发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接