您的位置:首页 > 其它

关于ListView中CheckBox选择混乱的问题

2017-06-15 23:59 375 查看
遇到了这个问题,记录下,方便以后查看,也让道友们看看

先上整体代码

public class MainActivity extends AppCompatActivity {

private ListView listView;
private List<Entity> list;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

listView = (ListView) findViewById(R.id.listView);

initData();

listView.setAdapter(new MyAdapter(this,list));

}

private void initData() {
list = new ArrayList<>();
for (int i = 0; i < 20; i++){
Entity entity = new Entity();
entity.isChecked = false;
entity.text = "这是第"+i+"条数据";
list.add(entity);
}
}

private class MyAdapter extends BaseAdapter{

private Context context;
private List<Entity> list;

MyAdapter(Context context,List<Entity> list){
this.context = context;
this.list = list;
}

@Override
public int getCount() {
return list.size();
}

@Override
public Object getItem(int position) {
return list.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position,View convertView,ViewGroup,parent){
ViewHolder holder;
if (convertView == null){
convertView = LayoutInflater.from(context)
.inflate(R.layout.list_item,parent,false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
final Entity data = list.get(position);
holder.checkBox.setChecked(data.isChecked);
holder.text.setText(data.text);
holder.checkBox.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
data.isChecked = isChecked;
}
});
return convertView;
}

class ViewHolder{

TextView text;
CheckBox checkBox;

public ViewHolder(View convertView){
text = (TextView) convertView.findViewById(R.id.title);
checkBox = (CheckBox) convertView
.findViewById(R.id.checkbox);
}

}
}

}


整体布局很简单,LinearLayout中放个ListView

ListView中的Item布局就是在LinearLayout中放了个TextView和一个CheckBox

如果不是用ViewHolder的话,是没问题的(可以自己试下),

上面通过ViewHolder来优化,出现选择混乱问题。

解决办法:

将holder.checkBox.setChecked(data.isChecked);

语句放在CheckBox选择改变监听事件后面,即可解决

原因分析

我们通过ViewHolder重用convertView,这时对于第一个条目,
我们选中后,滑动ListView,下面出来的item会重用第一个消息item的布局

再看我们的代码,每次根据list中对应position初始化checkbox状态,
看着好像也没问题,但是事实出现了问题...

一直以为是重用convertView的时候系统会给我们重置一些状态,后来发现不是...

我们勾选第一个item的 checkbox,然后滑动ListView到第一个条目消失,
这时最下面的item是重用第一个item的布局的,
这时我们初始化布局信息或状态,但是在初始化CheckBox状态时,使用的数据
为list中对应position的数据,此时监听事件还未重置,
监听事件改变的数据依旧是list中第一个数据,导致初始化CheckBox的时候
将第一个条目的数据也改变了所以导致滑动回来后,之前选择的取消选择了

因此将初始化CheckBox状态的语句放在设置完监听事件后就正常了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息