ListView嵌套CheckBox出现的复用问题
使用ListView嵌套CheckBox时使用简单地复用会出现复用的问题,像这种问题是很常见的。
这里说一下如何解决,首先如果不了解抽象适配,请移步我前面关于抽象适配器的博客,上代码:
第一种方法
ListView listview = (ListView) findViewById(R.id.main_cart_listview);
List<CartItemInfo> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(new CartItemInfo(1+i,"商品"+i,12+i*3,"",10+i*5,false));
}
HashMap<Long,Boolean> map = new HashMap<>();
listview.setAdapter(new SingleEasyAdapter<CartItemInfo>(getApplicationContext(), R.layout.cart_item, list, 3) {
@Override
public void bindData4View(ViewHolder holder, CartItemInfo data) {
holder.setText(R.id.item_cart_pdid,data.getPdId()+"")
.setText(R.id.item_cart_tv_pdname,data.getPdName())
.setText(R.id.item_cart_editnum_et, data.getPdNum() + "")
.setText(R.id.item_cart_price, data.getPdPrice() + "");
CheckBox cb = (CheckBox) holder.getView(R.id.item_cart_cb);
cb.setTag(data.getPdId());
cb.setChecked(map.get(data.getPdId()) == null ? false : map.get(data.getPdId()));
}
@Override
public void bindListener4View(ViewHolder holder) {
CheckBox cb = (CheckBox) holder.getView(R.id.item_cart_cb);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
map.put((Long) buttonView.getTag(),isChecked);
}
});
}
});
CartItemInfo不需要在意,就是一个实体类,需要注意的地方有
1.使用了一个map来存储选中的项目的id
2.需要将id设置到CheckBox的Tag中,取id也要从Tag中取得,不然数据改变之后id也会改变。
第二种方法
ListView listview = (ListView) findViewById(R.id.main_cart_listview);
List<CartItemInfo> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(new CartItemInfo(1+i,"商品"+i,12+i*3,"",10+i*5,false));
}
listview.setAdapter(new SingleEasyAdapter<CartItemInfo>(getApplicationContext(), R.layout.cart_item, list, 3) {
@Override
public void bindData4View(ViewHolder holder, CartItemInfo data) {
holder.setText(R.id.item_cart_pdid,data.getPdId()+"")
.setText(R.id.item_cart_tv_pdname,data.getPdName())
.setText(R.id.item_cart_editnum_et, data.getPdNum() + "")
.setText(R.id.item_cart_price, data.getPdPrice() + "");
CheckBox cb = (CheckBox) holder.getView(R.id.item_cart_cb);
cb.setTag(data);
cb.setChecked(data.isChecked());
}
@Override
public void bindListener4View(ViewHolder holder) {
CheckBox cb = (CheckBox) holder.getView(R.id.item_cart_cb);
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
((CartItemInfo)buttonView.getTag()).setIsChecked(isChecked);
}
});
}
});
这里在实体类CartItemInfo中添加了一个属性,boolean类型,通过他来设置 是否选中,需要注意的还是需要使用tag来传递实体类,否则会出现复用问题。
对比两种方法
怎么说呢,各有利弊,大多数人可能偏向于第二种方法,但是我们不得不考虑一个问题,当你想把所有的项目的选中状态改变为未选中,使用map.clear()要简单的多,当你的数据全部刷新,插入增加或者删除时,需要将所有的Item重置。