当我获得要分配给它的新列表时,如何在 RecyclerView 旧数据列表中正确通知 ItemMoved、插入和删除

How to properly notifyItemMoved, insert and removed in RecyclerView old data list when i get new fresh list to assign to it

我正在我的 RecyclerView 适配器中一次性填充新数据,因此没有插入或删除一项操作。

很简单,我有一个旧列表,当某些事件发生时,我会得到新列表,然后我可以将新列表分配给旧列表。

问题是我无法为旧列表中的每个项目正确制作动画

这是我现在拥有的东西,我认为它适用于第一种情况 - 项目移动到新位置:

     if(currentAdapterData!= null){
            for(int i = 0; i < currentAdapterData.size(); i++){
                for(int j = 0; j < newData.size(); j++){
                    if(currentAdapterData.get(i).getSomeIdentifier().equals(newData.get(j).getSomeIdentifier())){
                        Log.v("same item", "currentAdapterData index :" + i  + " ," + currentAdapterData.get(i).getSomeIdentifier() + " == newData index: " + j + " ," + newData.get(j).getSomeIdentifier());
                        if(i != j){
                            notifyItemMoved(i, j);
                        }
                    }
                }
            }
        }

        currentAdapterData = newData;

但是它没有按预期工作,并且日志(正确)和出现在 phone 上的列表之间存在差异(项目位置错误、一些重复、错误等)

那么我怎样才能让它发挥作用呢?使用 notifyItemMoved、notifyItemInserted 和 notifyItemRemoved?

我不想只使用 NofifyDataSetChanged,因为它会刷新整个列表,而不是仅仅用已更改的动画更新项目。

看来你的新数据也是列表的形式,不是单项。我认为这可能是在支持库中使用 DiffUtil 的一个很好的候选者。 Here 也是一个很好的教程。

它将允许您计算新数据的差异并只更新需要的字段。它还将异步卸载工作。

您只需要实现一个 DiffUtil.Callback 来指示您的项目是否相同或内容是否相同。

你像这样更新你的 recyclerView:

DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);
diffResult.dispatchUpdatesTo(yourAdapter);

像这样使用DiffUtil就可以了

final MyDiffCallback diffCallback = new MyDiffCallback(prevList, newList); final DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(diffCallback);

通过扩展 MyDiffCallback 和覆盖方法创建回调,并根据需要执行。

public class MyDiffCallback extends DiffUtil.Callback

// 覆盖方法

好吧,我觉得这是 easiest.Just 跟着它 ->

替换这个

if(currentAdapterData!= null){
        for(int i = 0; i < currentAdapterData.size(); i++){
            for(int j = 0; j < newData.size(); j++){
                if(currentAdapterData.get(i).getSomeIdentifier().equals(newData.get(j).getSomeIdentifier())){
                    Log.v("same item", "currentAdapterData index :" + i  + " ," + currentAdapterData.get(i).getSomeIdentifier() + " == newData index: " + j + " ," + newData.get(j).getSomeIdentifier());
                    if(i != j){
                        notifyItemMoved(i, j);
                    }
                }
            }
        }
    }

    currentAdapterData = newData;

if(currentAdapterData!= null){
        for(int i = 0; i < currentAdapterData.size(); i++){
            for(int j = 0; j < newData.size(); j++){
                if(currentAdapterData.get(i).getSomeIdentifier().equals(newData.get(j).getSomeIdentifier())){
                    Log.v("same item", "currentAdapterData index :" + i  + " ," + currentAdapterData.get(i).getSomeIdentifier() + " == newData index: " + j + " ," + newData.get(j).getSomeIdentifier());
                    if(i != j){
                        notifyDataSetChanged();
                       new CountDownTimer(250, 250) {

                                @Override
                                public void onTick(long millisUntilFinished) {
                                    Log.d("millisUntilFinished", "" + millisUntilFinished);
                                }

                                @Override
                                public void onFinish() {
                                    notifyItemMoved(i, j);
                                }
                        }.start();                      
                    }
                }
            }
        }
    }

这将更新值并在 250 毫秒(1/4 秒)后,值随动画一起移动。