2011-12-07 44 views
3

我發現herehere類似的問題,但問題稍有不同。android:ListView中的複選框(選中元素的奇怪行爲)

在一個ListView中,我嘗試把一個適配器(從基礎適配器擴展)的內容複選框。

列表視圖佈局:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    style="@style/mainLayout" 
> 

    <Button 
     android:id="@+id/close_cat" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:onClick="buttonClick" 
     android:text="@string/back" /> 

    <ListView 
     android:id="@android:id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 

</LinearLayout> 

XML列表的元素:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal" > 

    <TableLayout 
     android:id="@+id/blocCheck" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="25px" 
     android:layout_marginTop="25px" 
     android:background="@color/black" > 

     <TableRow 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:baselineAligned="true" 
      android:paddingLeft="4sp" > 

      <LinearLayout 
       android:layout_width="fill_parent" 
       android:layout_height="wrap_content" 
       android:layout_gravity="center_vertical" 
       android:layout_weight="1" 
       android:orientation="horizontal" 
       android:paddingLeft="20sp" > 

       <ImageView 
        android:id="@+id/iv_cat" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" /> 

       <TextView 
        android:id="@+id/category" 
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:layout_gravity="left" 
        android:layout_marginLeft="15dip" 
        android:text="tfgldkjhglf" 
        android:textSize="20sp" /> 
      </LinearLayout> 

      <CheckBox 
       android:id="@+id/check_cat" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_gravity="right" 
       android:layout_marginRight="10sp" 
       android:onClick="MyHandler" /> 
     </TableRow> 
    </TableLayout> 

</LinearLayout> 

我設置適配器在我看來:

list = getListView(); 
list.setAdapter(new CatAdapter(this, listCat)); 

我的適配器:

public class CatAdapter extends BaseAdapter { 

    private LayoutInflater mInflater; 
    private List<CatAdapterObject> mListAppInfo; 
    private Context mContext; 


    /** 
    * Constructor 
    * @param context 
    * @param data 
    * @param resource 
    * @param from 
    * @param to 
    */ 
    public CatAdapter (Context context, List<CatAdapterObject> list){ 
     mContext = context; 
     mListAppInfo = list; 
     mInflater = LayoutInflater.from(mContext);  
    } 

    /** 
    * number of elements 
    */ 
    @Override 
    public int getCount() { 
     return mListAppInfo.size(); 
    } 

    /** 
    * get an item in the list 
    */ 
    @Override 
    public Object getItem (int position){ 
     return mListAppInfo.get(position).getId(); 
    } 

    /** 
    * get id of the selected item 
    */ 
    @Override 
    public long getItemId(int position) { 
     return mListAppInfo.get(position).getId(); 
    } 

    /** 
    * get the view 
    */ 
    @Override 
    public View getView (int position, View convertView, ViewGroup parent){ 

     LinearLayout layoutItem; 

     if (convertView == null) { 
      layoutItem = (LinearLayout) mInflater.inflate(R.layout.category, parent, false); 
     } else { 
      layoutItem = (LinearLayout) convertView; 
     } 

     // get the current category 
     CatAdapterObject entry = mListAppInfo.get(position); 

     //view setting 
     TextView category = (TextView) layoutItem.findViewById(R.id.category); 
     CheckBox cb   = (CheckBox) layoutItem.findViewById(R.id.check_cat); 
     ImageView iv_cat = (ImageView) layoutItem.findViewById(R.id.iv_cat); 

     //elements setting 
     category.setText(entry.getName()); 

     //checkbox 
     cb.setChecked(entry.isChecked()); 
     cb.setTag(position); 

     //picture 
     Bitmap icon = Utils.getResizedBitmap(BitmapFactory.decodeResource(mContext.getResources(),entry.getPict()),45,45,true);  
     iv_cat.setImageBitmap(icon); 

     return layoutItem; 

    } 
} 

活動啓動時,列表顯示完美。我可以向上/向下滾動,沒有任何問題。但是,當我檢查其中一個複選框並向下滾動時,檢查標記被勾選的框以及列表中最新框的背景顏色被更改。

當檢查中,以下方法被調用(在我的活動文件):

public void MyHandler(View v) { 

     //クリックされたcheckbox 
     cb = (CheckBox) v; 

     Log.d("CHECKBOX","before :"+Utils.implode(",",this.cat_id_list)); 

     //get position in the list 
     Integer position = Integer.parseInt(cb.getTag().toString()); 

     //instance of the view (list's child) 
     View o = list.getChildAt(position).findViewById(R.id.blocCheck); 

     // check if box is checked 
     if (cb.isChecked()) { 
      o.setBackgroundResource(R.color.pink); 

      this.cat_id_list.add(position.toString()); 

     // 背景色を替え、リストから削除 
     } else { 

      o.setBackgroundResource(R.color.black); 

      Collections.sort(this.cat_id_list); 
      int index = Collections.binarySearch(this.cat_id_list,position.toString()); 
      this.cat_id_list.remove(index); 

     } 

     Log.d("CHECKBOX","after :"+Utils.implode(",",this.cat_id_list)); 
    } 

有我的列表中的8個元素,但是當我檢查清單「mChildrenCount」,只有5元素。

我只是想保存在「this.cat_id_list」id的元素,檢查和更改選定項目的背景顏色。

我將不勝感激您的幫助!

回答

4

在你getView你必須是這樣的(這個代碼是給你一個想法將如何工作你的情況):

ListView lv = ((ListActivity)context).getListView(); 
// Containing all check states 
SparseBooleanArray sba = lv.getCheckedItemPositions(); 

CheckBox cb = (CheckBox) convertView.findViewById(R.id.yourcheckbox); 

cb.setChecked(false); 

if(sba != null) 
    if(sba.get(position)) 
    cb.setChecked(true); 

認爲這需要在活動方面的內容。

您已通過android:choiceMode在xml或使用setChoiceMode使ListView成爲多選模式。您的複選框應該是不可點擊的且不可聚焦的。

您必須在按鈕上移除onClick偵聽器。無論您在onClick按鈕上做什麼,都必須將該邏輯添加到ListActivtiy的onListItemClick。

+0

謝謝。我爲我的XML列表設置了「android:choiceMode =」multipleChoice「」,將列表設置爲不可點擊的(list.setItemsCanFocus(false);)並在我的getView方法中嘗試代碼,但我知道如何設置遊標。我有搜索,但我不明白SparseBooleanArray的邏輯。庫爾布你給我更多細節? – johann

+0

不知道?我也試着用arrayAdapter和simpleAdapter ..沒有成功。 – johann

+0

你已使CheckBox不可點擊不列出項目....我也更新了代碼..如果您使用CursorAdapter,遊標一是好的 – havexz

3

我也有同樣的問題。我用下面的方法解決了它。
我創建了一個bean類來設置複選框的選中屬性,並使用ArrayAdapterArrayAdpater擴展了bean類。

Bean類

public class MCSSCheckState 
{ 
    private boolean isChecked; 
    public boolean getIsChecked() 
    { 
     return isChecked; 
    } 
    public void setIsChecked(boolean isChecked) 
    { 
     this.isChecked = isChecked; 
    } 
} 

的Java類

ArrayList<MCSSCheckState> mTitleList = new ArrayList<MCSSCheckState>(); 
MCSSCheckState check_state=new MCSSCheckState(); 
check_state.setIsChecked(false); 
mTitleList.add(i, check_state); 
ListAdapters adapter = new ListAdapters(this,R.id.camTitleTextView, mTitleList); 
ListView mListView = (ListView) findViewById(R.id.cameraListView); 
mListView.setAdapter(adapter); 

適配器類別

private class ListAdapters extends ArrayAdapter<MCSSCheckState> 
{ 
    private ArrayList<MCSSCheckState> items; 
    private int position;  
    public ListAdapters(Context context, int textViewResourceId, 
         ArrayList<MCSSCheckState> mTitleList) 
         { 
          super(context, textViewResourceId, mTitleList); 
          this.items = mTitleList; 
         } 
         @Override 
         public View getView(int position, View convertView, ViewGroup parent) 
         { 
          View v = convertView; 
          this.position = position; 
          if (v == null) 
          { 
           LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
           v = inflater.inflate(R.layout.camerslistinflater, null); 
          } 
          MCSSCheckState o = (MCSSCheckState) items.get(position); 
          if (o != null) 
          { 
           checkBox = (CheckBox) v.findViewById(R.id.checkBox1); 
           checkBox.setTag(position); 
           checkBox.setChecked(o.getIsChecked()); 
           checkBox.setOnClickListener(new OnClickListener() 
           { 
            @Override 
            public void onClick(View v) 
            { 
             MCSSCheckState obj = (MCSSCheckState) items.get(Integer.parseInt(v.getTag().toString())); 
             obj.setIsChecked(((CheckBox)v).isChecked()); 
             items.set(Integer.parseInt(v.getTag().toString()), obj);      
            } 
           }); 
          } 
          return v; 
         }); 
} 

希望這有助於你。

+0

謝謝你的代碼。我不明白你的bean類。爲什麼不使用SparseBooleanArray類?在我的列表中,我想設置複選框,但也包括圖片和文字。 – johann