繁体   English   中英

如何在Recycler视图中自动更新商品数据?

[英]How to automatically update items data in recycler view?

假设其中有一个包含CardViewRecyclerView ,在每个卡中,即项目中有两个TextView一个用于表示设备名称,另一个用于rssi级别,因此,当用户刷新数据时,只有rssi会刷新整个数据列表刷新。

我已经在RecyclerView获得了数据,但是重复了它而不是对其进行了更新。

型号类别:-

import android.support.annotation.NonNull;

public class RepeaterModel implements Comparable,Cloneable{

    public String macdev;
    public int rssi ;
    public int imageid;

    public RepeaterModel(String macdev, int rssi, int imageid) {
        this.macdev = macdev;
        this.rssi = rssi;
        this.imageid = imageid;
    }

    public String getMacdev() {
        return macdev;
    }

    public void setMacdev(String macdev) {
        this.macdev = macdev;
    }

    public int getRssi() {
        return rssi;
    }

    public void setRssi(int rssi) {
        this.rssi = rssi;
    }

    public int getImageid() {
        return imageid;
    }

    public void setImageid(int imageid) {
        this.imageid = imageid;
    }



    @Override
    public int compareTo(@NonNull Object o) {
        RepeaterModel compare =(RepeaterModel)o;
        if(compare.getMacdev().equals(this.macdev) && compare.getImageid()==this.imageid && compare.getRssi()==this.rssi)
        {
            return 0;
        }
        return 1;
    }

    @Override
    public RepeaterModel clone()
    {
        RepeaterModel clone;
        try {
            clone = (RepeaterModel) super.clone();

        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e); //should not happen
        }

        return clone;

    }
}

设备适配器类:-

public class ReapeaterDeviceAdapter extends RecyclerView.Adapter<ReapeaterDeviceAdapter.CryptoViewHolder> {

    private ArrayList<RepeaterModel> data;

    public class CryptoViewHolder extends RecyclerView.ViewHolder {

        private TextView mName, mPrice;

        public CryptoViewHolder(View itemView) {
            super(itemView);
            mName = itemView.findViewById(R.id.txtName);
            mPrice = itemView.findViewById(R.id.txtPrice);
        }
    }

    public ReapeaterDeviceAdapter(ArrayList<RepeaterModel> data) {
        this.data = data;
    }

    @Override
    public CryptoViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.repeater_dev_data,parent, false);
        return new CryptoViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(CryptoViewHolder holder, int position) {
        holder.mName.setText(data.get(position).macdev);
        holder.mPrice.setText(String.valueOf(data.get(position).rssi));
    }

    @Override
    public void onBindViewHolder(CryptoViewHolder holder, int position, List<Object> payloads) {

        if (payloads.isEmpty()) {
            super.onBindViewHolder(holder, position, payloads);
        } else {
            Bundle o = (Bundle) payloads.get(0);

            for (String key : o.keySet()) {
                if (key.equals("price")) {
                    holder.mName.setText(data.get(position).macdev);
                    holder.mPrice.setText(String.valueOf(data.get(position).rssi));
                    holder.mPrice.setTextColor(Color.GREEN);
                    this.notifyItemChanged(position);
                }
            }
        }
    }

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

    public ArrayList<RepeaterModel> getData() {
        return data;
    }

    public void setData(ArrayList<RepeaterModel> newData) {

        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new MyDiffUtilCallBack(newData, data));
        diffResult.dispatchUpdatesTo(this);
        data.clear();
        this.data.addAll(newData);
        //this.notifyDataSetChanged();
    }
}

DiffUtilCallback类:-

public class MyDiffUtilCallBack extends DiffUtil.Callback {
    ArrayList<RepeaterModel> newList;
    ArrayList<RepeaterModel> oldList;

    public MyDiffUtilCallBack(ArrayList<RepeaterModel> newList, ArrayList<RepeaterModel> oldList) {
        this.newList = newList;
        this.oldList = oldList;
    }

    @Override
    public int getOldListSize() {
        return oldList != null ? oldList.size() : 0;
    }

    @Override
    public int getNewListSize() {
        return newList != null ? newList.size() : 0;
    }

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

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

    @Nullable
    @Override
    public Object getChangePayload(int oldItemPosition, int newItemPosition) {

        RepeaterModel newModel = newList.get(newItemPosition);
        RepeaterModel oldModel = oldList.get(oldItemPosition);

        Bundle diff = new Bundle();
        if(newModel.getMacdev().equals(oldModel.getMacdev()) ) {
            if (newModel.rssi != (oldModel.rssi)) {
                diff.putInt("price", newModel.rssi);
            }
            if (diff.size() == 0) {
                return null;
            }
        }
        return diff;
        //return super.getChangePayload(oldItemPosition, newItemPosition);
    }
}

假设您的适配器有一个私有字段mItems和一个公共方法,如下所示

public void setItems(List<YourClass> items){
    mItems= items;
    notifyDataSetChanged();
}

调用此方法将刷新您的回收站视图。 另外,您可以像这样简单地通知适配器:

yourAdapterInstance.notifyDataSetChanged();

DiffCallback的实现无法正常工作:

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

使用equals方法而不是'=='

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

另外,删除this.notifyItemChanged(position); 来自方法public void onBindViewHolder(CryptoViewHolder holder, int position, List<Object> payloads) {另外,在分派更新之前,您也需要更新列表。

public void setData(ArrayList<RepeaterModel> newData) {

    DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new 
    MyDiffUtilCallBack(newData, data));

    data.clear();
    this.data.addAll(newData);
    diffResult.dispatchUpdatesTo(this);
}

PS:代码可能无法正常工作,将颜色更改为“绿色”可能会影响“未更新”的项目以便回收。 最好通过将已编辑/更新的信息添加到模型来更改RepeaterModel。

您应该只设置一次adapterrecylerview.setAdapter(adapter)在要更改Arraylist数据的任何其他地方,请使用adapter.notifyDatasetChanged()刷新列表。 它将仅刷新更改,而不刷新整个列表。

资料来源: https : //medium.com/@suragch/updating-data-in-an-android-recyclerview-842e56adbfd8

您应该将notifyItemChanged()与自定义对象一起使用,而不是notifyDatasetChanged。

创建具有2个成员的数据类,例如UpdateRecord

data class UpdateRecord(val _name : String? , val _rssi :String?)

当rssi更改时,请调用适配器的

notifyItemChange(position, UpdateRecord(null, newRssi))

您将收到onBindViewHolder(position,payload)调用,有效负载中的第一个对象是UpdateRecord对象。 检查并做

val updateRecord = payload[0] as UpdateRecord
if (updateRecord._name != null) {
  // update name text view
}
if (updateRecord._rssi != null) {
  // update rssi text view
}

这是RecyclerView中的部分更新机制,该机制仅更新更改的内容。

暂无
暂无

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

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