RecyclerView嵌入CheckBox带来的显示问题的解决办法
RecyclerView嵌入CheckB,ListView嵌入CheckBox2016-11-11
android 的recyclerview(或者是listview)内部item的布局包含checkbox控件时,会遇到常见的问题:选择的checkbox后滑动listview内容时会checkbox选择的值会刷新成原来状态值(即没选中),选择listview所有checkbox值之后,只能获取当前可见的checkbox的值,向后滑动选择的值无法获取。就像下图所示,总共是有50条数据,开始的时候50条数据都没有选中,后面选中前5条数据,然后滑动列表,发现checkbox的选中状态会产生错位的现象。
我们先来看看开始的时候代码是如何写的:
MainActivity:
package com.example.yk.checkboxsingle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private List<String> stringList;
public static Map<Integer,Boolean> map;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView= (RecyclerView) findViewById(R.id.recycler);
stringList=new ArrayList<>();
map=new HashMap<>();
for (int i = 0; i < 50; i++) {
stringList.add("第"+i+"条数据");
}
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayout.HORIZONTAL,1,R.color.line));
MyAdapter adapter=new MyAdapter(stringList,this);
recyclerView.setAdapter(adapter);
}
}MyAdapter:
package com.example.yk.checkboxsingle;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import java.util.List;
/**
* Created by yk on 2016/11/11.
*/
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder>{
private List<String> data;
private Context context;
public MyAdapter(List<String> stringList,Context context) {
this.data=stringList;
this.context=context;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view= LayoutInflater.from(context).inflate(R.layout.item_layout,parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.checkBox.setTag(position);
holder.checkBox.setText(data.get(position));
}
@Override
public int getItemCount() {
return data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private CheckBox checkBox;
public ViewHolder(View itemView) {
super(itemView);
checkBox= (CheckBox) itemView.findViewById(R.id.cb_my);
}
}
}
解决以上问题可以采取以下思路:
重写Adapter的getView方法时,为每个checkbox添加事件响应并记录选择状态,通过获取获取状态记录值获取所有选择的checkbox值。
解决办法主要是在onBindViewHolder方法重处理:
@Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
holder.checkBox.setText(data.get(position));
final Integer tag=new Integer(position);//初始化一个Integer实例,其值为position
holder.checkBox.setTag(tag);
if (MainActivity.map.containsKey(tag)){
holder.checkBox.setChecked(true);
}else {
holder.checkBox.setChecked(false);
}
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (holder.checkBox.isChecked()){
MainActivity.map.put(tag,true);
}else {
MainActivity.map.put(tag,false);
}
}
});
}效果如图:刚开始50条数据都没选中,后来选中前3条,滑动列表,并没有产生错位。
源码下载:点击打开链接
参考文章:
1、Recycleview checkbox 复用出现混乱解决方法:http://blog.csdn.net/fangchao3652/article/details/44103945
2、完美解决ListView和CheckBox焦点冲突及复用时CheckBox错位等一系列问题:http://blog.csdn.net/zhangjinhuang/article/details/49561893
第二篇文章介绍了:解决ListView和CheckBox焦点冲突;CheckBox的选择、全选、反选、删除的实现;下拉刷新,上拉加载checkbox的选中错位等问题。