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的选中错位等问题。