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

**

写前叨叨

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

开始说事儿

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

android RecyclerView 条目点击效果_android

首先由很多个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而且还要改变他正真的勾选状态。

请看效果图

android RecyclerView 条目点击效果_CheckBox_02


无论怎么选怎么滑他的状态都不会发生变化了。

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

写后叨叨

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