在開(kāi)發(fā)類(lèi)似購(gòu)物車(chē)編輯功能時(shí)遇到了CheckBox選擇狀態(tài)復(fù)用問(wèn)題。
一言不合先上圖:

寫(xiě)法一:
CheckBox checkBox = holder.getView(R.id.checkbox);
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});
很顯然,我們并沒(méi)有用代碼去控制CheckBox的checked狀態(tài),因此導(dǎo)致ListView滑動(dòng)的時(shí)候復(fù)用了CheckBox。所以我們可以加入Map集合,控制CheckBox顯示狀態(tài)。key記錄position或者唯一id,value記錄true或false的狀態(tài)。
寫(xiě)法二:
//注意:全局定義
private HashMap<Long, Boolean> checkedMap = new HashMap<>();
/*以下是Adapter中代碼*/
CheckBox checkBox = holder.getView(R.id.checkbox);
if (checkedMap.containsKey(getItem(position).getRelationId())
&& checkedMap.get(getItem(position).getRelationId())) {
//如果Map中存在此消息,并且已選中
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int tag = (int) buttonView.getTag();
checkedMap.put(getItem(tag).getRelationId(), isChecked);
notifyDataSetChanged();
}
});
依照寫(xiě)法二我們可以在onCheckedChanged方法中設(shè)置Map的key和value,然后調(diào)用notifyDataSetChanged()通知Adapter刷新?tīng)顟B(tài)。
然而并沒(méi)有什么卵用

當(dāng)我們給CheckBox設(shè)置不同狀態(tài)以后,滑動(dòng)ListView時(shí),發(fā)現(xiàn)CheckBox的狀態(tài)發(fā)生了錯(cuò)亂,通過(guò)斷點(diǎn)調(diào)試,發(fā)現(xiàn)Map中的數(shù)據(jù)是在改變的,從而導(dǎo)致CheckBox狀態(tài)錯(cuò)亂,而真正能修改Map的地方只有onCheckedChanged方法,果不其然,滾動(dòng)竟然導(dǎo)致了onCheckedChanged方法執(zhí)行。
那么問(wèn)題來(lái)了,咋搞?。?!
原來(lái)是代碼順序出現(xiàn)了問(wèn)題,我們先設(shè)置了CheckBox狀態(tài),然后再去設(shè)置了狀態(tài)改變監(jiān)聽(tīng)器。由于狀態(tài)的改變,導(dǎo)致onCheckedChanged方法執(zhí)行。
寫(xiě)法三
checkBox.setTag(position);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
int tag = (int) buttonView.getTag();
checkedMap.put(getItem(tag).getRelationId(), isChecked);
notifyDataSetChanged();
}
});
if (checkedMap.containsKey(getItem(position).getRelationId())
&& checkedMap.get(getItem(position).getRelationId())) {
//如果Map中存在此消息,并且已選中
checkBox.setChecked(true);
} else {
checkBox.setChecked(false);
}
搞定!
先去噓噓~