有没有遇到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;
}
}
}));
写后叨叨
做编程就得要有耐心,善于发现问题,结局问题,多总结吧,来到编程行业也不久,发现越来越喜欢这个行业,也希望我越走越远。
感谢大家的捧场。