[关闭]
@coder-pig 2015-09-22T07:44:45.000000Z 字数 3204 阅读 1504

Android基础入门教程——2.4.5 ListView之checkbox错位问题解决

Android基础入门教程


本节引言:

作为ListView经典问题之一,如果你尝试过自定义ListView的item,在上面带有一个checkbox的话,那么
当你的item数超过了一页的话,就会出现这个问题,下面我们来分析下出现这种问题的原因,以及如何来
解决这个问题!


1.问题发生的原因:

这是网上找来的一幅关于ListView getView方法调用机制的一个图

上图中有一个Recycler的东东,平时我们ListView上可见的Item处于内存中,而且他的Item则放在
这个Recycler中,第一次加载item时,当前页面中的convertView都为NULL,当滚出屏幕,这是时候
ConvertView不为空,所以新的一项会复用这个ConvertView!
我们可以写个简单的例子,跟下log,下面是运行后的一些Log图!

从图中看出,Postion从12开始,ConvertView就不为空了,具体这里代表的是什么,
我也不知道,目测要走源码...我们知道这里ConvertView会缓存就好,就是因为这个原因
造成的checkbox错位,所以第一个解决方式就是,不重用这个ConvertView,或者
说每次getView都将这个ConvertView设置为null,但是如果需要显示的Item数目巨大的话,
这种方法就会显得非常臃肿,一般实际开发我们使用的是下面的解决方法:
找个东东来保存当前Item CheckBox的状态,初始化的时候进行判断,设置是否选中!


2.解决方法示例:

好的存储这个Checkbox的方法有很多,你可以放到一个HashMap中,
每次初始化的时候根据postion取出对应的boolean值,然后再进行checkbox的状态设置;
而笔者的做法则是在entity类中加入了一个boolean值用于判断,下面是笔者一个项目中
抽取出来的代码,代码比较简单,相信你看完会秒懂的~

Entity类:Person.java

  1. public class Person implements Serializable{
  2. private String name;
  3. private String number;
  4. private boolean checkStatus;
  5. public Person(String name, String number) {
  6. super();
  7. this.name = name;
  8. this.number = number;
  9. this.checkStatus = false;
  10. }
  11. public String getName() {
  12. return name;
  13. }
  14. public void setName(String name) {
  15. this.name = name;
  16. }
  17. public String getNumber() {
  18. return number;
  19. }
  20. public void setNumber(String number) {
  21. this.number = number;
  22. }
  23. public boolean getCheckStatus() {
  24. return checkStatus;
  25. }
  26. public void setCheckStatus(boolean checkStatus) {
  27. this.checkStatus = checkStatus;
  28. }
  29. }

实现的Adapter类:ContactListAdapter.java

  1. public class ContactListAdapter extends BaseAdapter implements CompoundButton.OnCheckedChangeListener{
  2. private List<Person> mData;
  3. private Context mContext;
  4. public ContactListAdapter(List<Person> data, Context context) {
  5. mData = data;
  6. mContext = context;
  7. }
  8. // 定义一个刷新数据的方法
  9. public void changeData(List<Person> data) {
  10. mData = data;
  11. notifyDataSetChanged();
  12. }
  13. @Override
  14. public int getCount() {
  15. return mData.size();
  16. }
  17. @Override
  18. public Person getItem(int position) {
  19. return mData.get(position);
  20. }
  21. @Override
  22. public long getItemId(int position) {
  23. return position;
  24. }
  25. @Override
  26. public View getView(int position, View convertView, ViewGroup parent) {
  27. final Person person = mData.get(position);
  28. ViewHolder viewHolder;
  29. if (convertView == null) {
  30. convertView = LayoutInflater.from(mContext).inflate(
  31. R.layout.item_contact, parent, false);
  32. viewHolder = new ViewHolder();
  33. viewHolder.ly = (RelativeLayout) convertView
  34. .findViewById(R.id.lyContactListItem);
  35. viewHolder.txtName = (TextView) convertView
  36. .findViewById(R.id.txtName);
  37. viewHolder.txtNumber = (TextView) convertView
  38. .findViewById(R.id.txtNumber);
  39. viewHolder.cbxStatus = (CheckBox) convertView
  40. .findViewById(R.id.cbxStatus);
  41. convertView.setTag(viewHolder);
  42. viewHolder.cbxStatus.setTag(person);
  43. } else {
  44. viewHolder = (ViewHolder) convertView.getTag();
  45. }
  46. viewHolder.cbxStatus.setOnCheckedChangeListener(this);
  47. viewHolder.cbxStatus.setChecked(person.getcheckStatus());
  48. viewHolder.txtName.setText(person.getName());
  49. viewHolder.txtNumber.setText(person.getNumber());
  50. return convertView;
  51. }
  52. @Override
  53. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  54. Person person = (Person)buttonView.getTag();
  55. person.setCheckStatus(isChecked);
  56. }
  57. private class ViewHolder {
  58. RelativeLayout ly;
  59. TextView txtName;
  60. TextView txtNumber;
  61. CheckBox cbxStatus;
  62. }
  63. }

嘿嘿,非常简单,另外别忘了一点:
checkbox监听器的方法要添加在初始化Checkbox状态的代码之前哦~


本节引言:

好的,本节给大家讲解了ListView的一个经典问题,ListView中checkbox错位的
问题解决,只需简单的添加一个记录checkbox选择状态的值,然后重写checkbox
点击事件的时候,先做判断~谢谢~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注