您的位置:首页 > 移动开发 > Android开发

Android RecyclerView中ViewHolder的复用导致数据错乱解决办法

2016-07-29 22:40 1991 查看
看图:



视觉效果、recyclerview的基本用法都不说了,超级简单,稍后看代码。

重点来说说item状态的保存问题,其实这个也不是什么新鲜问题,处理起来也不难,方法众多,有setTag的,也有保存到map的。接下来我展示一种自认为更优的方式。

先描述问题,如上图,我们选中了第三个item。然后滑动RecyclerView,让第三个item移出界面后,在滑回来,item的状态是否还在?

由于滑动,view的复用,会丢失之前item选中的状态,但是,但是,item上显示的数据为什么没有错乱呢?这是因为数据集合没有错乱。那么我们能不能把item上需要保存的状态,也与数据集合一同保存呢?这样是不是就不会错乱。当然可以,这样更容易理解。

在数据集合中需要预留本地字段来保存状态。

适配器中的部分代码:

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.VH> {
//...
private ArrayList<UserBean> mLists = new ArrayList<>();
//...
}


故,UserBean中添加字段:

public class UserBean {

//后台返回的json字段
public String userName;
public String userPwd;
//...

//本地字段,用户recyclerview保存状态
public boolean isSelected = false;
}


在适配器中操作的核心部分代码:

/**
* @DateTime: 2016-07-26 14:31
* @Author: duke
* @Deacription:
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.VH> {
//...
private ArrayList<UserBean> mLists = new ArrayList<>();

//记录上次的位置和容器
private LinearLayout oldContainer;
private int oldPosition;

@Override
public void onBindViewHolder(VH holder, final int position) {
//强制关闭复用
//holder.setIsRecyclable(false);
final UserBean user = this.mLists.get(position);
holder.word.setText(user.userName);
if (user.isSelected) {
//选中的样式
holder.container.setBackgroundResource(R.drawable.item_bg_press);
} else {
//未选中的样式
holder.container.setBackgroundResource(R.drawable.item_bg);
}
holder.container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (listener != null)
listener.onDKClick(view, mLists.get(position), position);
//复原old位置
if (oldContainer != null) {
oldContainer.setBackgroundResource(R.drawable.item_bg);
if (oldPosition >= 0 && oldPosition < MyAdapter.this.mLists.size())
MyAdapter.this.mLists.get(oldPosition).isSelected = false;
}
//设置新的位置样式
oldContainer = (LinearLayout) view;
oldPosition = position;

oldContainer.setBackgroundResource(R.drawable.item_bg_press);
MyAdapter.this.mLists.get(oldPosition).isSelected = true;
}
});
}

//...
}


1、当对当前item做点击等事件操作时,需要把当前状态值保存到对应集合的对象中去。

2、复位上一个被点击的item状态。

3、当再次展示该item赋值时,根据集合中对应对象的数据来初始化item状态。

就是这么简单,直观易懂。listview、gridview等雷同的问题都可以这么解决。

http://download.csdn.net/detail/fesdgasdgasdg/9883490
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息