RecyclerView中CheckBox无效.

有没有遇到checkbox明明选中了,但是在滑动的过程中选中的又编程不选中了,ChexkBox选择无效

**

写前叨叨

*:
最近走公司项目,本来时间就特别紧张,每天都在不停的写,有时候稍不注意就是想让你爆粗口。

开始说事儿

接下来请看需求,就是一个简单的页面中加载了很多个checkbox列表,毫无疑问,首先我想到的是列表用RecyclerView,然后每个item中放入checkbox,很简单的麻,开始撸,结果没撸多久就出现以下的问题,先看效果图:
RecyclerView中CheckBox无效. - 阿里云

首先由很多个checkbox在勾选为选中状态后上拉,下拉,what!!又变为未选中状态,这让我如何是好。

先看代码
MainActivity

package com.ddh.recyclerviewbug;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity { private RecyclerView mRecyclerView; private List<MyData> mDataList = new ArrayList<>(); private MyAdapter mMyAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); indata(); mRecyclerView = (RecyclerView) findViewById(R.id.rv); //设置RecyclerView的适配器 LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(layoutManager); mMyAdapter = new MyAdapter(mDataList, this); mRecyclerView.setAdapter(mMyAdapter); } private void indata() { mDataList.add(new MyData(true, "Java编程语言")); mDataList.add(new MyData(false, "Java编程思想")); mDataList.add(new MyData(true, "Effective Java中文版")); mDataList.add(new MyData(false, "Java与模式")); mDataList.add(new MyData(true, ".NET程序设计技术内幕")); mDataList.add(new MyData(false, "C语言大全")); mDataList.add(new MyData(true, "Windows 程序设计")); mDataList.add(new MyData(false, "应用密码学")); mDataList.add(new MyData(true, "Intel微处理器结构")); mDataList.add(new MyData(false, "计算机网络第四版中文版")); mDataList.add(new MyData(true, "高级TCP/IP编程")); mDataList.add(new MyData(false, "计算机程序设计艺术")); mDataList.add(new MyData(true, "Windows 图形编程")); mDataList.add(new MyData(false, "设计模式")); mDataList.add(new MyData(true, "深入理解计算机系统")); mDataList.add(new MyData(false, "游戏之旅")); mDataList.add(new MyData(true, "高级TCP/IP编程")); mDataList.add(new MyData(false, "计算机程序设计艺术")); mDataList.add(new MyData(true, "Windows 图形编程")); mDataList.add(new MyData(false, "设计模式")); mDataList.add(new MyData(true, "深入理解计算机系统")); mDataList.add(new MyData(false, "游戏之旅")); mDataList.add(new MyData(true, "高级TCP/IP编程")); mDataList.add(new MyData(false, "计算机程序设计艺术")); mDataList.add(new MyData(true, "Windows 图形编程")); mDataList.add(new MyData(false, "设计模式")); mDataList.add(new MyData(true, "深入理解计算机系统")); mDataList.add(new MyData(false, "游戏之旅")); mDataList.add(new MyData(true, "Windows Mobile手机应用开发")); mDataList.add(new MyData(false, "单片机轻松入门")); mDataList.add(new MyData(true, "无线电识图与电路故障分析轻松入门")); mDataList.add(new MyData(false, "例说8051")); mDataList.add(new MyData(true, "Direct3D游戏编程入门教程")); mDataList.add(new MyData(false, "面向对象的游戏开发")); mDataList.add(new MyData(true, "Java 游戏高级编程")); mDataList.add(new MyData(false, "linux技术手册")); }}

MyAdapter

package com.ddh.recyclerviewbug;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.ArrayList;import java.util.List;/** * Created by 黄先生 on 2017/8/8. */public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> { private List<MyData> list = new ArrayList<>(); private Context context; private MyAdapter mMyAdapter;// private SparseBooleanArray mCheckStates = new SparseBooleanArray(); public MyAdapter(List<MyData> mList, Context mContext) { list = mList; context = mContext; } @Override public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (context == null) { context = parent.getContext(); } View mView = LayoutInflater.from(context).inflate(R.layout.item_my, parent, false); ViewHolder mViewHolder = new ViewHolder(mView); return mViewHolder; } @Override public void onBindViewHolder(final MyAdapter.ViewHolder holder, int position) { MyData mMyData = list.get(position); holder.mCheckBox.setChecked(mMyData.ischecked()); holder.mCheckBox.setText(mMyData.getName()); } @Override public int getItemCount() { return list.size(); } public class ViewHolder extends RecyclerView.ViewHolder { private CheckBox mCheckBox; public ViewHolder(View itemView) { super(itemView); mCheckBox = (CheckBox) itemView.findViewById(R.id.cb_itemmy); } }}

MyData

package com.ddh.recyclerviewbug;import java.io.Serializable;/** * Created by 黄先生 on 2017/8/8. */public class MyData implements Serializable { private boolean ischecked; private String name; public MyData(boolean mIschecked, String mName) { ischecked = mIschecked; name = mName; } public MyData() { } public boolean ischecked() { return ischecked; } public void setIschecked(boolean mIschecked) { ischecked = mIschecked; } public String getName() { return name; } public void setName(String mName) { name = mName; }}

activity_main

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.ddh.recyclerviewbug.MainActivity"><android.support.v7.widget.RecyclerView android:id="@+id/rv" android:layout_width="match_parent" android:layout_height="match_parent"></android.support.v7.widget.RecyclerView></LinearLayout>

item_my

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <CheckBox android:id="@+id/cb_itemmy" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="5dp" android:layout_marginTop="5dp"/></LinearLayout>

实在是再简单不过的代码了可就偏偏发生了奇葩,为毛。
静下心来想一下,为何叫RecyclerView?难道和这个有关??

原来真的和这个有关,recuclerview利用复用机制,当recyclerview滑动的时候会调用Adapter中的onBindViewHolder方法重新加载未出现在屏幕上的checxbox;

原因找到了,那就soga…
每次在选中或者取消选中的时候不光要改变UI而且还要改变他正真的勾选状态。

请看效果图
RecyclerView中CheckBox无效. - 阿里云
无论怎么选怎么滑他的状态都不会发生变化了。

这样一来问题得以解决,主要是在MainActivity中加了以下的代码

mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this, new RecyclerItemClickListener.OnItemClickListener() { @Override public void onItemClick(View view, int position) { MyData mData = mDataList.get(position); if (mData.ischecked()) { mMyAdapter.notifyDataSetChanged(); mData.setIschecked(false); return; } if (!mData.ischecked()) { mData.setIschecked(true); mMyAdapter.notifyDataSetChanged(); return; } } }));

写后叨叨

做编程就得要有耐心,善于发现问题,结局问题,多总结吧,来到编程行业也不久,发现越来越喜欢这个行业,也希望我越走越远。
感谢大家的捧场。