2014-10-01 66 views
2

我在一個適配器中使用了一個getView,我正在創建一個imageview並使之等於convertView,其中視圖已經被初始化了。它包含圖像縮略圖,其中一些代表視頻。在這個getView,編程視圖生成中初始化RelativeLayout

@Override 
    public View getView(int position, View convertView, ViewGroup container) { 
     // First check if this is the top row 

     if (position < mNumColumns) { 
      if (convertView == null) { 
       convertView = new View(mContext); 
      } 
      // Set empty view with height of ActionBar 
      //convertView.setLayoutParams(new AbsListView.LayoutParams(
      //  LayoutParams.MATCH_PARENT, mActionBarHeight)); 
      return convertView; 
     } 

     // Now handle the main ImageView thumbnails 
     ImageView imageView; 
     if (convertView == null) { // if it's not recycled, instantiate and initialize 
      imageView = new RecyclingImageView(mContext); 
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
      imageView.setLayoutParams(mImageViewLayoutParams); 
     } else { // Otherwise re-use the converted view 
      imageView = (ImageView) convertView; 
     } 

     // Check the height matches our calculated column width 
     if (imageView.getLayoutParams().height != mItemHeight) { 
      imageView.setLayoutParams(mImageViewLayoutParams); 
     } 

     imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 

     if(images.get(position - mNumColumns).getUriString().contains("video")){ 
      //display video icon 
     } 
     else 
     { 
      //don't display video icon 
     } 

     // Finally load the image asynchronously into the ImageView, this also takes care of 
     // setting a placeholder image while the background thread runs 
     if (images != null && !images.isEmpty()) 
      mImageFetcher.loadImage(images.get(position - mNumColumns).getUriString()/*.imageUrls[position - mNumColumns]*/, imageView); 
     return imageView; 
    } 

縮略圖沒有一個「播放」按鈕,對他們來指定,他們是視頻,所以在這種情況下,我需要添加一個播放按鈕,編程。

通常情況下,我使用了一個帶有膨脹佈局的視圖模式,在這種情況下我沒有這樣做,因爲我實際上不想在內存中使用某些東西。

所以不是我想以編程方式做出RelativeLayout的每個單元(mRelativeLayout = (RelativeLayout)convertView)的根視圖,並添加ImageView的和PLAYBUTTON ImageView的成convertview

我該怎麼辦呢?它要求本聲明的修改,但我不知道如何初始化全部重新使用的視圖

} else { // Otherwise re-use the converted view 
      imageView = (ImageView) convertView; 
     } 
+0

爲什麼你性別編程的觀點,你可以使用xml – Lokesh 2014-10-20 08:02:37

+0

我有你的問題的答案,但使用XML文件,其中我顯示播放按鈕。 – Lokesh 2014-10-20 08:03:48

+0

@ lokeshjoshi786現在以編程方式執行 – CQM 2014-10-20 14:15:32

回答

2
的性能損失

我會讓你的getView()始終返回一個RelativeLayout對象(我將其稱爲containerView),您將其作爲子女添加到ImageView(s)

這裏唯一的問題是您需要給這些孩子標識符,以便您可以稍後從回收的convertView中檢索它們。請注意,我爲此使用了內置靜態View.generateViewId(),這是API級別17.如果您需要它在API-level-17之前工作,則可以使用唯一整數(例如1,2等)創建自己的ID ) - 只要確保它們不大於0x0FFFFFF更新:我在下面添加了代碼。

查看我在以下幾點添加的評論。

@Override 
public View getView(int position, View convertView, ViewGroup container) { 
    // First check if this is the top row 
    if (position < mNumColumns) { 
     if (convertView == null) { 
      convertView = new View(mContext); 
     } 
     // Set empty view with height of ActionBar 
     //convertView.setLayoutParams(new AbsListView.LayoutParams(
     //  LayoutParams.MATCH_PARENT, mActionBarHeight)); 
     return convertView; 
    } 

    // Now handle the main ImageView thumbnails 
    RelativeLayout containerView; 
    ImageView imageView; 
    ImageView videoIconView; // TODO: or whatever type you want to use for this... 
    if (convertView == null) { // if it's not recycled, instantiate and initialize 
     containerView = new RelativeLayout(mContext); 
     // TODO: The layout params that you used for the image view you probably 
     // now want to use for the container view instead... 
     imageView.setLayoutParams(mImageViewLayoutParams); // If so, you can change their name... 

     imageView = new RecyclingImageView(mContext); 
     imageView.setScaleType(ImageView.ScaleType.CENTER_CROP); 
     //imageView.setLayoutParams(mImageViewLayoutParams); // This probably isn't needed any more. 

     // Generate an Id to use for later retrieval of the imageView... 
     // This assumes it was initialized to -1 in the constructor to mark it being unset. 
     // Note, this could be done elsewhere in this adapter class (such as in 
     // the constructor when mImageId is initialized, since it only 
     // needs to be done once (not once per view) -- I'm just doing it here 
     // to avoid having to show any other functions. 
     if (mImageId == -1) { 
      mImageId = View.generateViewId(); 
     } 
     imageView.setId(mImageId); 

     containerView.addView(imageView, RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT); 

     // NOTE: At this point, I would personally always just add the video icon 
     // as a child of containerView here no matter what (generating another unique 
     // view Id for it, mVideoIconId, similar to how was shown above for the imageView) 
     // and then set it to either VISIBLE or INVISIBLE/GONE below depending on whether 
     // the URL contains the word "video" or not. 
     // For example: 
     vidoIconView = new <whatever>; 
     // TODO: setup videoIconView with the proper drawable, scaling, etc. here... 
     if (mVideoIconId == -1) { 
      mVideoIconId = View.generateViewId(); 
     } 
     videoIconView.setId(mVideoIconId); 
     containerView.addView(videoIconView, RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); 
     final RelativeLayout.LayoutParams layout = ((RelativeLayout.LayoutParams)containerView.getLayoutParams()); 
     layout.addRule(RelativeLayout.LayoutParams.CENTER_HORIZONTAL); // ... or whatever else you want 
     layout.addRule(RelativeLayout.LayoutParams.ALIGN_PARENT_BOTTOM); // ... or whatever else you want 
    } else { 
     // Otherwise re-use the converted view 
     containerView = (RelativeLayout) convertView; 
     imageView = containerView.findViewById(mImageId); 
     videoIconView = containerView.findViewById(mVideoIconId); // see comment above 
    } 


    // Check the height matches our calculated column width 
    if (containerView.getLayoutParams().height != mItemHeight) { 
     containerView.setLayoutParams(mImageViewLayoutParams); 
    } 

    if(images.get(position - mNumColumns).getUriString().contains("video")){ 
     //display video icon 
     // see comment above, here you can probably just do something like: 
     videoIconView.setVisibility(View.VISIBLE); 
    } 
    else 
    { 
     //don't display video icon 
     videoIconView.setVisibility(View.GONE); // could also use INVISIBLE here... up to you. 
    } 

    // Finally load the image asynchronously into the ImageView, this also takes care of 
    // setting a placeholder image while the background thread runs 
    if (images != null && !images.isEmpty()) 
     mImageFetcher.loadImage(images.get(position - mNumColumns).getUriString()/*.imageUrls[position - mNumColumns]*/, imageView); 
    return containerView; 
} 

更新:
針對在評論的問題,我用的是這樣的(在我的自定義 「的ViewController」 基類):

private static int s_nextGeneratedId = 1; 

/** 
* Try to do the same thing as View.generateViewId() when using API level < 17. 
* @return Unique integer that can be used with setId() on a View. 
*/ 
protected static int generateViewId() { 
    // AAPT-generated IDs have the high byte nonzero; clamp to the range under that. 
    if (++s_nextGeneratedId > 0x00FFFFFF) 
     s_nextGeneratedId = 1; // Roll over to 1, not 0. 
    return s_nextGeneratedId; 
} 

請注意,您不需要網格中每個單元格的唯一視圖ID。相反,您只需要使用findViewById()就可以訪問的每種類型的子視圖。所以在你的情況下,你可能只需要兩個獨特的ID。由於從您的xml佈局文件自動生成的視圖ID通常非常大,因此我發現使用低數字手動生成的ID(如上所示)很方便。

+0

來做到這一點,謝謝,你能否詳細說明如果我必須自己創建ID,View.generateViewId()是如何工作的?我覺得我不得不在這裏使用隨機數字生成器,因爲我將無法引用其他單元格 – CQM 2014-10-21 14:27:43

+0

@CQM我剛更新了我的答案以解決這個問題。特別是,我不認爲你需要使用隨機數字發生器。你可以簡單地使用'1'和'2',比如說'''mImageId'和'2'代表'mVideoIconId'。 (我假設你不是在你的應用程序的任何其他地方生成手工生成的視圖ID)。 – Turix 2014-10-21 18:52:42

+0

我試圖在授予賞金之前使其工作,但是在自動選擇StackOverflow之前仍然有困難。這是一個比XML更好的答案 – CQM 2014-10-22 16:33:32

3

我覺得這裏最好的辦法是使用返回不同類型的視圖的適配器(由優先於getViewTypeCount()getItemViewType()),例如如this answer中所述。

這樣你就不需要以編程方式修改返回的視圖。只需定義兩個XML佈局,然後根據該位置的項目是否有視頻,對其中一個或另一個進行膨脹/重用。

這不僅是清晰的,你不會有「轉化」一種觀點認爲到時的視頻行作爲convertView提供用於其他項目其他沒有一個,或者反之亦然

+0

當然,所以這更關於如何以編程方式創建第二個視圖。這個問題並不涉及定義一個XML佈局:)我知道如何用XML – CQM 2014-10-15 16:31:38

相關問題