2012-08-06 54 views
1

我正在實現一個支持多項選擇的圖像庫。主要佈局是使用自定義AdapterGridView。每個顯示的項目都是組合ImageView + CheckBox。如果選中了多個複選框,我想只需觸摸GridView中的任何圖像即可取消選中它們。我打電話notifyDataSetChanged()來實現此功能。不幸的是,這個「全部取消」功能不起作用。我仍然是一個新手,所以可能有一些基本的東西我不明白。有人能告訴我我的Adapter有什麼問題嗎?謝謝。帶有自定義ImageAdapter的GridView在數據集更改後不會更新

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 

    // References to our images 
    public Integer[] mThumbIds = { 
      R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, 
      R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, 
      R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3, 
      R.drawable.sample_1, R.drawable.sample_2, R.drawable.sample_3 
    }; 

    // The layout inflater used to retrieve gallery children layouts 
    private LayoutInflater mInflater; 

    // Array used to update checkboxes 
    public boolean[] checkboxesState = new boolean[getCount()]; 

    public ImageAdapter(Context c) { 
     mContext = c; 
     mInflater = (LayoutInflater) 
       c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

     // Define the initial checked/unchecked state of the checkboxes 
     for(int i = 0; i < getCount(); i++) { 
      checkboxesState[i] = false; 
     } 
    } 

    public int getCount() { 
     return mThumbIds.length; 
    } 

    public Object getItem(int position) { 
     return position; 
    } 

    public long getItemId(int position) { 
     return position; 
    } 

    /* Create a new View for each cell displayed in the GridView. 
    * In our case a View is an instance of RelativeLayout from which 
    * we can extract the image and checkbox to be displayed in the cell 
    */ 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View cell = convertView; 
     if (cell == null) { 
      // No View passed, create one. 
      cell = mInflater.inflate(R.layout.galleryitem, null); 
      // Setup the View content 
      ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage); 
      CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox); 
      checkBox.setChecked(checkboxesState[position]); 
      checkBox.setId(position); 
      imageView.setImageBitmap(downsample(mThumbIds[position])); 

      // Setup the View behavior 
      imageView.setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 
        // Uncheck all checked items 
        uncheckAll(); 
       } 
      }); 

      checkBox.setOnClickListener(new OnClickListener() { 
       public void onClick(View v) { 
        CheckBox cb = (CheckBox) v; 
        checkboxesState[cb.getId()] = cb.isChecked(); 
       } 
      }); 
     } 
     return cell; 
    } 

    private Bitmap downsample(int resId){ 
     // Some code here 
    } 

    private void uncheckAll() { 
     // This code does not work. GridView is not refreshed 
     for(int i = 0; i < checkboxesState.length; i++) { 
      checkboxesState[i] = false; 
     } 
     notifyDataSetChanged(); 
    } 
} 

更新

我已經意識到我的初始後並沒有確切地描述了uncheckAll方法是如何失敗的。當我有N個選中的複選框,並調用會發生什麼uncheckAll方法是:

  • 最初選中的複選框是選中
  • ň複選框一批新的檢查

這種行爲讓我覺得也許gridview項目意外地改變了他們在GridView中的位置,所以我爲每個項目添加了一個TextView以及一個唯一的名稱。我的想法是正確的:當我滾動屏幕時,項目在GridView中改變其位置。當uncheckAll被調用時會發生同樣的情況。我找到了適用於我的解決方案in this thread

注:我一開始並沒有意識到移動問題,因爲在這個開發階段,我對GridView項每個使用相同的ImageView資源。

回答

1

問題很可能是您的getView()方法正確地初始化新的單元格視圖,但從不更新已回收的單元格視圖的狀態。所以基本上每個單元格視圖將只顯示它初始化的狀態。它應該是這個樣子:

public View getView(int position, View convertView, ViewGroup parent) { 
    View cell = convertView; 

    if (cell == null) { 
     // No View passed, create one. 
     cell = mInflater.inflate(R.layout.galleryitem, null); 
     // Setup the View content 
     ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage); 
     CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox); 
     checkBox.setChecked(checkboxesState[position]); 
     checkBox.setId(position); 
     imageView.setImageBitmap(downsample(mThumbIds[position])); 

     // Setup the View behavior 
     imageView.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       // Uncheck all checked items 
       uncheckAll(); 
      } 
     }); 

     checkBox.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { 
       CheckBox cb = (CheckBox) v; 
       checkboxesState[cb.getId()] = cb.isChecked(); 
      } 
     }); 
    } else { 
     ImageView imageView = (ImageView)cell.findViewById(R.id.thumbImage); 
     CheckBox checkBox = (CheckBox) cell.findViewById(R.id.itemCheckBox); 
     checkBox.setChecked(checkboxesState[position]); 
     checkBox.setId(position); 
     imageView.setImageBitmap(downsample(mThumbIds[position])); 
    } 

    return cell; 
} 

此外,以提高您的getView()方法的性能,看看這個tutorial

+0

感謝您的回答。它指向我在後更新中提到的線程的相同方向,並且工作正常。我不知道該教程。我會嘗試將其應用於我的代碼。 – Vicent 2012-08-07 06:32:53

+0

四年後,我給你一個upvote,對吧?那麼我能說什麼?這個讓我發瘋了!謝謝! – ZengoTim 2016-10-15 16:40:52

相關問題