首先:參考了這篇翻譯的文章:http://www.cnblogs.com/xiaowenji/archive/2010/12/08/1900579.html
文章中關於說的Android中的Recycler比較模糊,Android會維持屏幕中顯示的item+1個對象。但是復用的時候選擇哪個對象來復用的機制並不明確,具體用的是什么數據結構,求告知。。。肯定不是簡單的FIFO或LIFO。
關於checkBox,選中了之后,下滑之后返回就消失的問題。有以下兩種方式供大家參考:
data是給TextView顯示的。
isChecked是用來記錄CheckBox是否選中的。
ArrayList<String> data; ArrayList<Boolean> isChecked;
class Holder {
TextView name;
CheckBox box;
}
一:
用onClickedListener,使用這個監聽器可以簡單的避開CheckedBox選中消失的問題。
其中:holder.box.setTag(i);用來給監聽器指明選擇的索引。
@Override public View getView(int i, View view, ViewGroup viewGroup) { if(view == null) { view = LayoutInflater.from(context).inflate(R.layout.list_item, null); holder = new Holder(); holder.box = (CheckBox) view.findViewById(R.id.cb_isChecked); holder.name = (TextView) view.findViewById(R.id.tv_name); view.setTag(holder); } else { holder = (Holder) view.getTag(); } holder.name.setText(data.get(i)); System.out.println("即將改變成" + isChecked.get(i) + "i" + i); holder.box.setChecked(isChecked.get(i));
holder.box.setTag(i); holder.box.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { boolean hold = isChecked.get((Integer) view.getTag()); isChecked.set((Integer) view.getTag(), !hold); System.out.println("compoundButton.getTag()" + view.getTag()); } }); return view; }
二.用onCheckedListener, 使用這個監聽器,需要注意一些問題。
代碼:和上面的一樣,就是把onClickListener改成onCheckedlistener,結果就出現了選中消失的問題。
仔細看了在logcat中看了輸出的結果,發現問題的所在:
當我們選中一個item時,假設此時item1被選中,下拉列表,到時item1隱藏,item10出現,並復用了item1的結構,由於在getView函數中item10被賦值是false,此時,onCheckedListener監聽器響應了(如果使用onClickedListener就沒有以下問題,因為它再此時不會響應),問題來了:
因為在onCheckedListener根據view.getTag()來獲得索引,而此時的索引是1,就是item1對象時setTag時留下的。
最終導致此時監聽器把用來存儲布爾值的線性表的索引1的位置賦值成了item10的值。
根據問題的成因,我們需要在 onCheckedListener響應前,讓view.getTag()獲得正確的索引,其實很簡單只需要將
holder.box.setTag(i);放到holder.box.setChecked(isChecked.get(i));前面就可以了。
此解決方案的完整代碼:
public class ListAdapter2 extends BaseAdapter {
ArrayList<String> data;
ArrayList<Boolean> isChecked;
Context context;
Holder holder;
public ListAdapter2(Context context, ArrayList<String> data, ArrayList<Boolean> isChecked) {
this.context = context;
this.data = data;
this.isChecked = isChecked;
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int i) {
return data.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
if(view == null) {
view = LayoutInflater.from(context).inflate(R.layout.list_item, null);
holder = new Holder();
holder.box = (CheckBox) view.findViewById(R.id.cb_isChecked);
holder.name = (TextView) view.findViewById(R.id.tv_name);
view.setTag(holder);
} else {
holder = (Holder) view.getTag();
}
holder.name.setText(data.get(i));
System.out.println("即將改變成" + isChecked.get(i) + "i" + i);
holder.box.setTag(i);
holder.box.setChecked(isChecked.get(i));
holder.box.setOnCheckedChangeListener(new CheckedListener());
return view;
}
class CheckedListener implements CompoundButton.OnCheckedChangeListener {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
isChecked.set((Integer) compoundButton.getTag(), b);
System.out.println("compoundButton.getTag()" + compoundButton.getTag() + "b" + b);
}
}
class Holder {
TextView name;
CheckBox box;
}
}
