原本以為已經把ListView搞的滿熟的了,沒想到今天要在自訂畫面的ListView中加一個CheckBox竟然搞了快四個小時才搞完它
雖然只是需要改動adapter中的一點點東西,但一直以為是自已元件用不熟,出了錯誤,一直在找自已錯在哪裡找不出來,實在是很痛苦
最後的錯誤在於:
若在自訂義ListView的情況下,如果設定了ListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE)
在item中若只有CheckedTextView的話就沒事,但若是自已訂議了有被包起來的CheckBox就會出事
網上的討論似乎是跟Android資源回收利用時會把View給刪掉再重開有關系
所以在這情況下,如果要使用onItemClickListener 或onListItemClick時,回傳的position會沒錯,可是position所對應的View會亂跳
每次按都不一定會回給你哪一個View。完完整整的亂掉,更有時候按一按就當掉了。
解決方法很簡單,只要把創造出來的每一個CheckBox都另外存起來 hold住,不讓系統回收掉就好了。
我參考了幾篇之中,以下這一篇寫的比較好:
http://www.itivy.com/android/archive/2011/12/14/android-listview-checkbox-problem.html
所以就以此篇作為基礎,自已寫了一個可以放入CheckBox的SimpleCursorAdapter供大家使用。
(寫完之後才發現原來我自已是要用CursorAdapter,只需依照相似的作法即可)
開一個新的class,將下面的東西放入,然後就可以呼叫著用了~!
比較不一樣的地方是,如果有CheckBox的部分,要將CheckBox的id放入 CheckBoxID欄位中,才會對應到。
import java.util.ArrayList; import java.util.Arrays; import java.util.List; import android.content.Context; import android.database.Cursor; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; abstract public class SimpleCheckedCursorAdapter extends BaseAdapter{ private boolean[] isSelected; private Context context = null; private LayoutInflater inflater = null; private Cursor cursor = null; private int resource = 0; private String keyString[] = null; private String itemString = null; private int idValue[] = null;// id private int checkboxID = 0; public class ViewHolder { public CheckBox cb = null; } public SimpleCheckedCursorAdapter(Context context, Cursor cursor, int resource, String[] from, int[] to, int checkboxID) { this.context = context; this.cursor = cursor; this.resource = resource; keyString = new String[from.length]; idValue = new int[to.length]; System.arraycopy(from, 0, keyString, 0, from.length); System.arraycopy(to, 0, idValue, 0, to.length); this.checkboxID = checkboxID; inflater = LayoutInflater.from(context); init(); } public void init() { cursor.moveToFirst(); isSelected = new boolean[getCount()]; Arrays.fill(isSelected, Boolean.FALSE); } public void toggle(View v, int pos){ ViewHolder holder = (ViewHolder) v.getTag(); holder.cb.toggle(); isSelected[pos] = holder.cb.isChecked(); } public long[] getCheckedItemIDs(){ List<Long> CheckedIDs = new ArrayList<Long>(); for(int i =0;i<isSelected.length;i++){ if(isSelected[i]){ cursor.moveToPosition(i); CheckedIDs.add(cursor.getLong(cursor.getColumnIndex("_id"))); } } long[] IDs = new long[CheckedIDs.size()]; for(int i=0;i<CheckedIDs.size();i++){ IDs[i]=CheckedIDs.get(i); } return IDs; } @Override public int getCount() { cursor.moveToFirst(); return cursor.getCount(); } @Override public Object getItem(int pos) { return null; } @Override public long getItemId(int pos) { return cursor.getLong(cursor.getColumnIndex("_id")); } @Override public View getView(int position, View view, ViewGroup arg2) { cursor.moveToPosition(position); ViewHolder holder = null; if (holder == null) { holder = new ViewHolder(); if (view == null) { view = inflater.inflate(resource, null); } for(int i=0;i<idValue.length;i++){ View v = view.findViewById(idValue[i]); itemString = cursor.getString(cursor.getColumnIndex(keyString[i])); if(v instanceof TextView){ TextView tv = (TextView) v; tv.setText(itemString); }else if(v instanceof EditText){ EditText et = (EditText) v; et.setText(itemString); }else if(v instanceof Button){ Button btn = (Button) v; btn.setText(itemString); }else if (v instanceof CheckBox){ CheckBox cb =(CheckBox) v; if(itemString.contentEquals("1")||itemString.contentEquals("0")){ cb.setChecked(itemString.contains("1")); }else{ cb.setText("itemString[i]"); } } } holder.cb = (CheckBox) view.findViewById(checkboxID); view.setTag(holder); } else { holder = (ViewHolder) view.getTag(); } holder.cb.setChecked(isSelected[position]); return view; } }
留言列表