首页 > 代码库 > CheckBox在ListView中的数据错乱

CheckBox在ListView中的数据错乱

  在ListView中,一般我们都会使用convertView参数,来滑动过程中,复用convertView对象来优化listView。但是如果在ListView中使用了CheckBox对象,就会出现数据错乱。比如我勾选了第一个item的CheckBox,往下滑动也会出现勾选的CheckBox。当然有些人说不优化,没次执行getView都创建一个view对象。但是那是非常不可取的,如果数据大的话,是非常要命的。本项目在实现优化的情况下,解决了CheckBox在ListView中的数据错乱,大家可以参考一下。也欢迎大家提供宝贵的意见。

 

 

activity_main.xml布局:

 

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:layout_width="match_parent" 4     android:layout_height="match_parent" 5     android:orientation="vertical" > 6      7     <LinearLayout  8         android:layout_width="match_parent" 9         android:layout_height="wrap_content"10         android:orientation="horizontal"11         >12         <CheckBox 13             android:id="@+id/cb_all"14             android:layout_width="wrap_content"15             android:layout_height="wrap_content"16             />17         <Button18             android:id="@+id/btn_del_checked" 19             android:layout_width="wrap_content"20             android:layout_height="wrap_content"21             android:text="@string/btn_del_checked"22             />23     </LinearLayout>24     <ListView 25         android:layout_width="match_parent"26         android:layout_height="0dp"27         android:layout_weight="1"28         android:id="@+id/lv_checkbox"29         />30 </LinearLayout>

activity_main_item.xml 布局:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2     xmlns:tools="http://schemas.android.com/tools" 3     android:layout_width="match_parent" 4     android:layout_height="wrap_content" 5     android:gravity="left" 6     android:orientation="horizontal"> 7     <CheckBox  8         android:id="@+id/item_ck" 9         android:layout_width="wrap_content"10         android:layout_height="wrap_content"11         />12     <TextView 13         android:id="@+id/item_tv_name"14         android:layout_width="wrap_content"15         android:layout_height="wrap_content"16         />17 </LinearLayout>

Persons.java文件

 1 package com.datian.andoridlistcheck.entity; 2  3  4 public class Person { 5  6     private String name; 7     private boolean isChecked; 8      9     public Person(String name, boolean isChecked) {10         super();11         this.name = name;12         this.isChecked = isChecked;13     }14 15     public Person() {16         super();17     }18 19     public String getName() {20         return name;21     }22 23     public void setName(String name) {24         this.name = name;25     }26 27     public boolean isChecked() {28         return isChecked;29     }30 31     public void setChecked(boolean isChecked) {32         this.isChecked = isChecked;33     }34     35     36 }

MainActivity.java 文件

 1 package com.datian.andoridlistcheck; 2  3 import java.util.ArrayList; 4 import java.util.List; 5  6 import com.datian.andoridlistcheck.adpter.CheckBoxAdpter; 7 import com.datian.andoridlistcheck.entity.Person; 8  9 import android.os.Bundle;10 import android.app.Activity;11 import android.content.Context;12 import android.view.View;13 import android.view.View.OnClickListener;14 import android.widget.Button;15 import android.widget.CheckBox;16 import android.widget.ListView;17 18 public class MainActivity extends Activity implements OnClickListener {19 20     private Context context = this;21     private List<Person> persons;22     private ListView lv_checkbox;23     private CheckBox cb_all;24     25     private CheckBoxAdpter checkBoxAdpter;26 27     @Override28     protected void onCreate(Bundle savedInstanceState) {29         super.onCreate(savedInstanceState);30         setContentView(R.layout.activity_main);31         initData();32         initWidget();33     }34 35     /**36      * 初始化控件37      */38     private void initWidget() {39         cb_all = (CheckBox) this.findViewById(R.id.cb_all);40         cb_all.setOnClickListener(this);41         42         43         checkBoxAdpter = new CheckBoxAdpter(context, persons,cb_all);44         lv_checkbox = (ListView) this.findViewById(R.id.lv_checkbox);45         lv_checkbox.setAdapter(checkBoxAdpter);46 47         48         Button btn_del_checked = (Button) this49                 .findViewById(R.id.btn_del_checked);50         btn_del_checked.setOnClickListener(this);51     }52 53     /**54      * 初始化数据55      */56     private void initData() {57         persons = new ArrayList<Person>();58         for (int i = 0; i < 20; i++) {59             persons.add(new Person("位置" + i, false));60         }61     }62 63     @Override64     public void onClick(View v) {65         switch (v.getId()) {66         case R.id.btn_del_checked: // 删除选中67              List<Person> checkedPersons = checkBoxAdpter.getCheckedPersons();68              for(int i = 0;i <checkedPersons.size();i++){69                  persons.remove(checkedPersons.get(i));70              }71             checkBoxAdpter.notifyDataSetChanged();72             break;73         case R.id.cb_all: // 全选或全不选74             boolean isChecked = cb_all.isChecked();75             for (int i = 0; i < persons.size(); i++) {76                 persons.get(i).setChecked(isChecked);77             }78             checkBoxAdpter.notifyDataSetChanged();79             break;80         }81     }82 }

CheckBoxAdpter.java文件 适配器。

  1 package com.datian.andoridlistcheck.adpter;  2   3 import java.util.ArrayList;  4 import java.util.List;  5 import com.datian.andoridlistcheck.R;  6 import com.datian.andoridlistcheck.entity.Person;  7   8 import android.content.Context;  9 import android.view.LayoutInflater; 10 import android.view.View; 11 import android.view.ViewGroup; 12 import android.widget.BaseAdapter; 13 import android.widget.CheckBox; 14 import android.widget.CompoundButton; 15 import android.widget.TextView; 16  17 /** 18  * @author datian 19  */ 20 public class CheckBoxAdpter extends BaseAdapter { 21  22     private LayoutInflater inflater; 23     private List<Person> persons; 24     private CheckBox cb_all; 25     public CheckBoxAdpter(Context context, List<Person> persons, CheckBox cb_all) { 26         this.inflater = LayoutInflater.from(context); 27         this.persons = persons; 28         this.cb_all = cb_all; 29     } 30  31     @Override 32     public int getCount() { 33         return persons.size(); 34     } 35  36     @Override 37     public Object getItem(int position) { 38         return persons.get(position); 39     } 40  41     @Override 42     public long getItemId(int position) { 43         return position; 44     } 45  46      47     @Override 48     public View getView(int position, View convertView, ViewGroup parent) { 49         final int pos = position; 50         HanlderView hanlderView = null; 51         if(convertView==null){ 52             hanlderView = new HanlderView(); 53             convertView = inflater.inflate(R.layout.activity_main_item, null); 54             hanlderView.item_ck = (CheckBox) convertView.findViewById(R.id.item_ck); 55             hanlderView.item_tv_name = (TextView) convertView.findViewById(R.id.item_tv_name); 56             convertView.setTag(hanlderView); 57         }else{ 58             hanlderView = (HanlderView) convertView.getTag(); 59         } 60          61         hanlderView.item_ck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 62             @Override 63             public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 64                 persons.get(pos).setChecked(isChecked); 65                 System.out.println("listener------"+persons.get(pos).getName()+":"+isChecked); 66                 if(isCheckedAll()){ 67                     cb_all.setChecked(true); 68                 }else{ 69                     cb_all.setChecked(false); 70                 } 71             } 72         }); 73          74         hanlderView.item_ck.setChecked(persons.get(pos).isChecked()); 75         System.out.println("list----"+pos+":"+persons.get(pos).isChecked()); 76         hanlderView.item_tv_name.setText(persons.get(position).getName()); 77         return convertView; 78     } 79  80     /** 81      * 获取被选中 82      * @return 被选中的集合list 83      */ 84     public List<Person> getCheckedPersons(){ 85         List<Person> checkedPersons = new ArrayList<Person>(); 86         for(int i = 0;i<persons.size();i++){ 87             if(persons.get(i).isChecked()){ 88                 checkedPersons.add(persons.get(i)); 89             } 90         } 91         return checkedPersons; 92     } 93      94     /** 95      * 判断是否全部选中 96      * @return 97      */ 98     private boolean isCheckedAll(){ 99         boolean flag = true;100         for(int i = 0;i < persons.size();i++){101             if(!persons.get(i).isChecked()){102                 flag = false;103                 break;104             }105         }106         return flag;107     }108     109     private class HanlderView{110         public CheckBox item_ck;111         public TextView item_tv_name;112     }113 }
 hanlderView.item_ck.setChecked(persons.get(pos).isChecked());这行必须要在setOnCheckedChangeListener监听的后面才行。