原本以為已經把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;
            }
}


arrow
arrow
    全站熱搜

    alderis 發表在 痞客邦 留言(2) 人氣()