Java 如何在“回收器”视图中自动更新项目数据?
假设其中有一个Java 如何在“回收器”视图中自动更新项目数据?,java,android,android-recyclerview,Java,Android,Android Recyclerview,假设其中有一个RecyclerView由CardView组成,在每个卡片(即项目)中有两个TextView,一个是设备名称,另一个是rssi级别,因此当用户刷新数据时,只有rssi会得到刷新,而不是整个列表得到刷新 我在RecyclerView中获得了数据,但它得到的是重复数据,而不是更新数据 模型类:- import android.support.annotation.NonNull; public class RepeaterModel implements Comparable,Clo
RecyclerView
由CardView
组成,在每个卡片(即项目)中有两个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();
}
}
公共类ReapeaterDeviceAdapter扩展了RecyclerView.Adapter{
私有数组列表数据;
公共类CryptoViewHolder扩展了RecyclerView.ViewHolder{
私有文本视图mName,mPrice;
公共CryptoViewHolder(查看项目视图){
超级(项目视图);
mName=itemView.findviewbyd(R.id.txtName);
mPrice=itemView.findviewbyd(R.id.txtPrice);
}
}
公共重复设备适配器(ArrayList数据){
这个数据=数据;
}
@凌驾
public CryptoViewHolder onCreateViewHolder(视图组父级,int-viewType){
View itemView=LayoutInflater.from(parent.getContext()).flate(R.layout.repeater\u dev\u data,parent,false);
返回新的CryptoViewHolder(itemView);
}
@凌驾
BindViewHolder上的公共无效(CryptoViewHolder,int位置){
holder.mName.setText(data.get(position.macdev));
holder.mPrice.setText(String.valueOf(data.get(position.rssi));
}
@凌驾
public void onBindViewHolder(CryptoViewHolder、int位置、列表有效负载){
if(payloads.isEmpty()){
super.onBindViewHolder(支架、位置、有效载荷);
}否则{
Bundle o=(Bundle)有效载荷。get(0);
用于(字符串键:o.keySet()){
if(键等于(“价格”)){
holder.mName.setText(data.get(position.macdev));
holder.mPrice.setText(String.valueOf(data.get(position.rssi));
holder.mPrice.setTextColor(Color.GREEN);
此项变更(位置);
}
}
}
}
@凌驾
public int getItemCount(){
返回data.size();
}
public ArrayList getData(){
返回数据;
}
public void setData(ArrayList newData){
DiffUtil.diffiesult diffiesult=DiffUtil.calculateDiff(新的MyDiffUtilCallBack(新数据,数据));
diffResult.dispatchUpdatesTo(本);
data.clear();
this.data.addAll(newData);
//this.notifyDataSetChanged();
}
}
DiffulicCallback类:-
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);
}
}
公共类MyDiffUtilCallBack扩展了DiffUtil.Callback{
ArrayList新列表;
ArrayList oldList;
公共MyDiffUtilCallBack(ArrayList新列表、ArrayList旧列表){
this.newList=newList;
this.oldList=oldList;
}
@凌驾
public int getOldListSize(){
返回oldList!=null?oldList.size():0;
}
@凌驾
public int getNewListSize(){
返回newList!=null?newList.size():0;
}
@凌驾
公共布尔值areItemsTheSame(int-oldItemPosition,int-newItemPosition){
返回newList.get(newItemPosition).getMacdev()==oldList.get(oldItemPosition).getMacdev();
}
@凌驾
公共布尔值是相同的内容(int oldItemPosition,int newItemPosition){
int result=newList.get(newItemPosition).compareTo(oldList.get(oldItemPosition));
返回结果==0;
}
@可空
@凌驾
公共对象getChangePayload(int-oldItemPosition、int-newItemPosition){
RepeaterModel newModel=newList.get(newItemPosition);
RepeaterModel oldModel=oldList.get(oldItemPosition);
Bundle diff=新Bundle();
if(newModel.getMacdev().equals(oldModel.getMacdev())){
if(newModel.rssi!=(oldModel.rssi)){
diff.putInt(“价格”,newModel.rssi);
}
如果(差异大小()==0){
返回null;
}
}
返回差;
//返回super.getChangePayload(oldItemPosition、newItemPosition);
}
}
您应该设置
适配器
,即recylerview.setAdapter(adapter)
仅一次。并且在更改阵列列表中数据的任何其他位置
使用适配器。notifyetchDataSanged()
刷新列表。它将只刷新更改,而不是整个列表
来源:假设适配器有一个私有字段
mItems
和一个公共方法,如下所示
public void setItems(List<YourClass> items){
mItems= items;
notifyDataSetChanged();
}
您应该对自定义对象使用notifyItemChanged(),而不是notifyDatasetChanged 创建包含2个成员的数据类say UpdateRecord
data class UpdateRecord(val _name : String? , val _rssi :String?)
当rssi发生变化时,调用适配器的
notifyItemChange(position, UpdateRecord(null, newRssi))
您将收到对BindViewHolder(位置,负载)的调用,负载中的第一个对象是UpdateRecord对象。检查并执行
val updateRecord = payload[0] as UpdateRecord
if (updateRecord._name != null) {
// update name text view
}
if (updateRecord._rssi != null) {
// update rssi text view
}
这是RecyclerView中的部分更新机制,仅更新更改的内容。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()) ;
}
另外,删除此.notifyItemChanged(位置)代码>从方法公开无效onBindViewHolder(CryptoViewHolder,int位置,列表有效载荷){
在发送更新之前,您还需要更新列表
public void setData(ArrayList<RepeaterModel> newData) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new
MyDiffUtilCallBack(newData, data));
data.clear();
this.data.addAll(newData);
diffResult.dispatchUpdatesTo(this);
}
public void setData(ArrayList newData){
DiffUtil.diffesult diffesult=DiffUtil.calculateDiff(新
MyDiffUtilCallBack(新数据,数据));
data.clear();
this.data.addAll(newData);
diffResult.dispatchUpdatesTo(本);
}
PS:代码可能无法正常工作,将颜色更改为绿色可能会影响“未更新”项目du的回收。最好通过将编辑/更新的信息添加到模型中来更改RepeaterModel。您是否可以共享您的代码或我们是否应该猜测?,更具体地说是“帮助他人重现问题”
public void setData(ArrayList<RepeaterModel> newData) {
DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new
MyDiffUtilCallBack(newData, data));
data.clear();
this.data.addAll(newData);
diffResult.dispatchUpdatesTo(this);
}