首页 > 代码库 > 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监听的后面才行。
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。