RecyclerView中CheckBox无效.

来源:互联网 发布:网络叫表妹是什么意思 编辑:程序博客网 时间:2024/06/05 17:16

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

**

写前叨叨

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

开始说事儿

接下来请看需求,就是一个简单的页面中加载了很多个checkbox列表,毫无疑问,首先我想到的是列表用RecyclerView,然后每个item中放入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而且还要改变他正真的勾选状态。

请看效果图
这里写图片描述
无论怎么选怎么滑他的状态都不会发生变化了。

这样一来问题得以解决,主要是在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;                }            }        }));

写后叨叨

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