繁体   English   中英

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

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

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

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

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

  • 当项目在新列表中具有新位置时(应将 notifyItemMoved 从旧位置移至新位置)
  • 当新列表中有新项目时(应该用新列表中的那个位置通知ItemInserted)
  • 当新列表中不存在旧项目时(应使用该位置通知项目移除)

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

     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;

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

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

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

看起来您的新数据也是一种列表形式,而不是单个项目。 我认为这可能是在支持库中使用DiffUtil的不错选择。 也是一个很好的教程。

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

您只需要实现一个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

// 覆盖方法

好吧,我觉得这将是最简单的。只要按照它 ->

替换这个

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 秒)后,随着动画移动该值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM