Android ListView中CheckBox错误问题解决

Android开发人员在很多很多场合都会用到ListView这个控件,无论封装过也好,原生态也好,今天我们要说的是在ListView中关于使用Checkbox的一些让人蛋疼的问题。

此文章来自于http://www.cnblogs.com/wujd/archive/2012/08/17/2635309.html的理解,谢谢这位朋友!

1.MainActivity代码如下,简单的不用解释

public class MainActivity extends Activity {
    private List<Person> list;
    private ListView mListView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        initView();
        //prepare data
        initData();
        //setting data
        Adapter adapter = new Adapter(list, this);
        mListView.setAdapter(adapter);
    }

    private void initView() {
        mListView = (ListView) findViewById(R.id.lv_test);
    }

    private void initData() {
        list = new ArrayList<Person>();
        Person person;
        for (int i = 0; i < 40; i++) {
            person = new Person(i + "号位", Person.TYPE_NOCHECKED);
            list.add(person);
        }
    }
}
2.我们定义一个实体类Person

public class Person {
	public static final int TYPE_CHECKED = 1;
	public static final int TYPE_NOCHECKED = 0;
	String name;
	int type;
	public Person(String name, int type) {
		this.name = name;
		this.type = type;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
}
3.主要是我们的Adapter了
public class Adapter extends BaseAdapter {

	private List<Person> mData;
	private Context context;

	public Adapter(List<Person> mData, Context context) {
		this.mData = mData;
		this.context = context;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			holder = new ViewHolder();
			convertView = View.inflate(context, R.layout.item, null);
			holder.textView = (TextView) convertView.findViewById(R.id.tv_test);
			holder.checkBox = (CheckBox) convertView.findViewById(R.id.cb_test);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		//prepare data
		final Person person = mData.get(position);
        //设置监听器代码必须要在设置CheckBox状态之前
		holder.checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				if (isChecked) {
					person.setType(Person.TYPE_CHECKED);
				} else {
					person.setType(Person.TYPE_NOCHECKED);
				}
			}
		});

        //setting status
        holder.textView.setText(person.getName());
        if (person.getType() == Person.TYPE_CHECKED) {
            holder.checkBox.setChecked(true);
        } else {
            holder.checkBox.setChecked(false);
        }

		return convertView;
	}

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

	@Override
	public Object getItem(int position) {
		return null;
	}

	@Override
	public long getItemId(int position) {
		return 0;
	}
}
class ViewHolder {
	TextView textView;
	CheckBox checkBox;
}
只需要记住一句话即可:设置监听器代码必须要在设置CheckBox状态之前。
错乱原因:添加监听器的代码在初始化checkBox属性的代码之后,也就是说当初始化checkBox属性时,由于可能改变其状态,导致调用了onCheckedChange()方法,而这个监听器是在上一次初始化的时候添加的,那么当然其index就是上一次的positon值,而不是本次的,所以每次保存checkBox属性状态的时候,都把值赋到的list集合里其它对象上去了,而不是与本次index相关的对象上。

解决原因:由于是因为index错误造成的,那么只要保证index值与当前positon保持一至即可,只要把添加监听器的方法加到初始化view中checkBox状态的代码之前即可.这样即始由于初始化造成调用了onCheckedChange()方法,也因为其中index值是最新的,而依然不会错乱.

下载Demo请猛戳

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值