8

我有一個帖子列表,其中大部分是圖片(簡單地說就是像G +或FB應用程序一樣的帖子)。每個帖子條目都有一個圖像寬高比,所以即使在圖像從服務器加載之前,我也可以根據它的寬度來設置圖像高度,因此卡片佈局在加載時不會改變。獲取CardView在Adapter.onBindViewHolder中的寬度

的問題是兩個卡後的圖像layout_width="match_parent"集。當我得到cardview的寬度時,它是零。所以我無法計算身高。

現在我看到的唯一的解決辦法是採取父容器(RecyclerView)的寬度並扣除所有的墊襯,但它看起來並不像一個很好的解決方案。

有沒有其他方法可以做到這一點?

下面是適配器代碼

@Override 
public void onBindViewHolder(ViewHolder holder, int position) { 
    .... 
    int width = holder.itemView.getWidth(); 
    .... 
    //do some calculations 
} 

佈局的例子(沒有不相關部分)

<?xml version="1.0" encoding="utf-8"?> 
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:card_view="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/card" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:descendantFocusability="blocksDescendants" 
    android:foreground="?android:attr/selectableItemBackground" 
    card_view:cardBackgroundColor="#ffffff" 
    card_view:cardCornerRadius="3dp"> 

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"> 

     <include 
      android:id="@+id/includedPost" 
      layout="@layout/post_details" />  
    </RelativeLayout> 
</android.support.v7.widget.CardView> 

includedPost:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 
    <ImageView 
     android:id="@+id/postImage" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:layout_below="@+id/commenterImage" 
     android:minHeight="120dp" 
     android:scaleType="centerCrop" /> 

</RelativeLayout> 
+1

你可以把你調用getWidth方法的一部分代碼(結果爲0)嗎? – 2014-10-28 10:46:55

+0

更新我的示例代碼 – Andrew 2014-10-28 11:04:20

+1

問題也許你可以嘗試調用的getWidth()在[onViewAttachedToWindow]法(https://developer.android.com/reference/android/support/v7/widget/RecyclerView.Adapter.html#onViewAttachedToWindow (VH))根據文檔:「這可以作爲一個合理的信號,該視圖即將被用戶看到」 – 2014-10-28 11:12:16

回答

7

onBindonViewAttachedToWindow叫,孩子是尚未測量,以便您無法獲得寬度。即使這些電話是在衡量孩子之後做出的,但你所要做的並不是一個好習慣,因爲改變身高需要一個新的測量。

如果使用LinearLayoutManager,它會給全寬子(預期RecyclerView填充和孩子的利潤)。這不是很好,但可以從那裏得到你的身高。

另一個(更靈活)這裏的方法是創建,讓您的長寬比自定義ImageView的。當調用onBind時,您將設置自定義ImageView的所需長寬比。 當測量被調用時,它將根據您的寬高比進行測量。

class MyImageView extends ImageVIew { 
     .... 
     private float mScale = 1f; 

     public void setScale(int scale) { 
      mScale = scale; 
     } 

     @Override 
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

      super.onMeasure(widthMeasureSpec, heightMeasureSpec); 

      int width = getMeasuredWidth(); 
      setMeasuredDimension(width, width * mScale); 
     } 
} 

所以在你的onBind方法中,你根據你的w/h比例在ImageView上調用setScale。

我還沒有測試過,但是這種方法應該按需要工作。

+0

太棒了!有用。 – Andrew 2014-10-29 08:51:40

+0

真的很棒,但setMeasuredDimension在你的檢查中有點混亂: int width = getMeasuredWidth(); int height = getMeasuredHeight(); setMeasuredDimension((int)(width * mScale),height); – cinatic 2016-07-03 11:46:36

0

您可以使用畢加索轉型來實現這一目標。

FitToTargetViewTransformation類:

import android.graphics.Bitmap; 
import android.view.View; 

import com.squareup.picasso.Transformation; 

/** 
* Picasso Transformation class to fit image to target View size 
*/ 
public class FitToTargetViewTransformation implements Transformation { 
    private View view; 

    public FitToTargetViewTransformation(View view) { 
    this.view = view; 
    } 

    @Override 
    public Bitmap transform(Bitmap source) { 
    int targetWidth = view.getWidth(); 

    double aspectRatio = (double) source.getHeight()/(double) source.getWidth(); 
    int targetHeight = (int) (targetWidth * aspectRatio); 
    if (source.getHeight() >= source.getWidth()) { 
     return source; 
    } 
    Bitmap result = Bitmap.createScaledBitmap(source, targetWidth, targetHeight, false); 
    if (result != source) { 
     // Same bitmap is returned if sizes are the same 
     source.recycle(); 
    } 
    return result; 
    } 

    @Override 
    public String key() { 
    return "transformation" + " desiredWidth"; 
    } 
} 

而且在某處onBindViewHolder你做這樣的事情:

Picasso.with(context) 
    .load(AVATAR_ENDPOINT) 
    .transform(new FitToTargetViewTransformation(feedViewHolder.icAvatar)) 
    .into(feedViewHolder.icAvatar); 
+0

我不相信它解決了我的問題。縮放圖像我沒有問題。我的問題是在加載圖像之前ImageView的設置大小,以防止在加載某些圖像時進一步調整卡的大小 – Andrew 2014-10-28 10:41:34