您的位置:首页 > 其它

ListView点击checkbox其他checkbox也被同时选中的问题

2017-11-22 20:32 309 查看


ListView点击checkbox其他checkbox也被同时选中的问题

假如ListView,分成2页(或者设置数据可以纵向拉,可隐藏),每页3条数据,每个Listview的Item 里面有个checkBox,现在,当我选择第一页的前两天数据,翻到第二页,竟然第二页后两条数据也选中了,这是绝对不允许的。经过本人的N次调试,发现public View getView(int position, View convertView, ViewGroup
parent)传进来的convertView 竟然产生多次重用。解决方案:当选中checkedBox时候,我们用一个List来保存该checkBox的position。然后在每次产生View时取得传来的convertView赋值为null,再遍历List里保存的checkBox的位置,当在数组内时,checkBox置为选中,问题解决了。

该问题有两种解决方案,个人目前所实现了的。

1.用HashMap保存checkbox的状态值。

HashMap<Integer, Boolean> state = new HashMap<Integer,Boolean>();

                     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {

                                // TODO Auto-generated method stub

                                if(isChecked)

                                {  

                                       state.put(position, isChecked);

                                        System.out.println("复选框以选中,选中的行数为:" + temp_position);

                                }else{

                                     state.remove(position);

                                }

                        }

在getView()方法里面: holder.cbox.setChecked(state.get(position)==null? false : true);

2.(不推荐使用,因为会产生许多垃圾对象)

public View getView(int position, View convertView, ViewGroup parent)在每次传进convertView时候,设为null。

然后每调用一次getView就产生一个view对象。

现象

   ListView中,当前点击的那行,设置为红色。往下滚动,发现隔11行或12行的那行也会变红色,但是你并没有点过它。

2.原因

  主要的问题在于自定义的Adapter中的getView()方法。一般我们会这样写:

    public View getView(int position, View convertView, ViewGroup parent) { 

        ZuJian zuJian = null; 

        if(convertView==null){ 

            zuJian = new ZuJian(); 

            // 获取组件布局 

            convertView = layoutInflater.inflate(R.layout.vlist2, null); 

            zuJian.imageView = (ImageView) convertView.findViewById(R.id.image); 

            zuJian.titleView = (TextView) convertView.findViewById(R.id.title); 

            zuJian.infoView = (TextView) convertView.findViewById(R.id.info); 

            zuJian.button = (Button) convertView.findViewById(R.id.view_btn); 

            // 这里要注意,是使用的tag来存储数据的。 

            convertView.setTag(zuJian); 

        } 

        else { 

            zuJian = (ZuJian) convertView.getTag(); 

        } 

   }

这样写的话,就会有问题了。因为我们知道View convertView只在第一页显示的那些item是被创建的,当你滚动到下一页的时候,就会重复使用,这时候就会出问题。

3.解决办法

    HashMap<Integer,View> lmap = new HashMap<Integer,View>();

    public View getView(int position, View convertView, ViewGroup parent) {

        View view;

        ViewHolder holder = null;

        

        if (lmap.get(position) == null) {            

            view = mInflater.inflate(R.layout.download_productdetail_item, null);

            holder = new ViewHolder();

            holder.txt_bookChapter = (TextView) view

                .findViewById(R.id.download_book_name);

            final int p = position;

            lmap.put(position, view);

            view.setTag(holder);

        }else{

            view = lmap.get(position);

            holder = (ViewHolder)view.getTag();

        }

   }

在这段代码中,我们可以看到一开始定义了一个HashMap<Integer,View> lmap,在getView()方法中,使用lmap.put(position, view)把每个view和position一一对应起来,对于已经建立的view,使用view = lmap.get(position)来取,这样既可以保存改变的状态,又不会重复。

listview中没行都有一个checkbox,为什么我选中一个checkbox而有的checkbox会自动选中呢?

会没隔9行会被选中,请高手们看看

系统会把出屏的View用来充当新入屏的View(这样不用再new了,只修改一下界面文字),这是优化。

所以有check框的view,你必须自己实现adapter,在每次getView的时候,根据情况,去打勾或者去掉勾。

主要是因为  getView 的问题。

你要继承Adapter ,构造函数中需要 初始化 一个map<Integer,Boolean>,去对应每个位置的checkbox,尤其要重写getView方法!

getView 方法中,还需要去改变map的值!让它记住上次checkbox的状态。

希望对你有帮助。

 ListView中的getChildCount()并不总是等于ListAdapter中的数据行数。当手机一屏显示不了所有数据时(需要翻页),getChildCount()就等于手机一屏幕所显示的行数,小于ListAdapter中的数据行数。而ListView的getCount()是与ListAdapter中的数据行数相同。

    当光标下移到屏幕最底部,新显示出来的View,最初的3个(不知道为什么是3个),在Adapter中调用getView(int position, View convertView, ViewGroup parent)方法中,会判断convertView为null,而再有新的View就会发现convertView不为空,所以新显示的View其实使用了之前某个View的对象。这就造成了状态可能混乱。比如第一行的checkbox点选时,第11行的也同时会被点选,

所以可以

     1) getView(int position, View convertView, ViewGroup parent){}

 方法每行的开始 写这样一行convertView = null;

     2) 用一个List记录你勾选过的每一行的LiseView index

摘抄自互联网,经过综合总结而成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐