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

来源:互联网 发布:开淘宝店怎么刷销量 编辑:程序博客网 时间:2024/05/21 06:32

遇到了这个问题,记录下,方便以后查看,也让道友们看看

先上整体代码

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状态的语句放在设置完监听事件后就正常了。
阅读全文
0 0
原创粉丝点击