2016-11-08 100 views
3

我需要將Bitmap設置爲ImageView以保持16:9的比例。你有什麼建議嗎?主要的解決方案可能是在自定義ImageView的覆蓋方法onMeasure但是如何?Android ImageView - 16:9

+0

[如何將Imageview中的百分比相對佈局設置爲基於設備屏幕大小的16:9,1:1,3:2,2:1,4:3](https: //stackoverflow.com/questions/36305054/how-to-set-imageview-in-percent-relative-layout-to-following-ratios-based-on-de) –

回答

2
public class CustomImageView extends ImageView { 

    // some other necessary things 

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

     int width = getMeasuredWidth(); 

     //force a 16:9 aspect ratio    
     int height = Math.round(width * .5625f); 
     setMeasuredDimension(width, height); 
    } 
} 

然後在你的XML

<path.to.package.CustomImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:src="@drawable/img"/> 
2

編輯:谷歌已正式棄用%的支持率文庫開始API 26,你應該遠離它,一旦動地。

集大小爲比率 可以視圖的大小設定爲比,如16:如果視圖尺寸中的至少一個被設置爲「匹配約束」 9(0dp)。要啓用比率,請單擊切換長寬比約束(圖10中的標註1),然後在顯示的輸入中輸入寬高比。

如果寬度和高度都設置爲匹配約束,則可以單擊切換長寬比約束以選擇基於另一維的比例的維。視圖檢查器通過用實線連接相應邊緣來指示將哪個設置爲比率。

例如,如果將兩側設置爲「匹配約束」,請單擊切換長寬比約束兩次以將寬度設置爲高度的比率。現在整個大小由圖(其可以以任何方式來限定)的高度決定,如圖如下:

The view is set to a 16:9 aspect with the width based on a ratio of the height.

的更多信息在這裏:https://developer.android.com/training/constraint-layout/index.html#adjust-the-view-size


支持庫中有一種叫PercentFrameLayoutPercentRelativeLayout的東西。

<android.support.percent.PercentFrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 
    <ImageView 
    app:layout_widthPercent="100%" 
    app:layout_aspectRatio="178%" 
    android:scaleType="centerCrop" 
    android:src="@drawable/header_background"/> 
    <!-- The rest of your layout --> 
</android.support.percent.PercentRelativeLayout> 

如果你看看上面的佈局仔細一看,你會發現有問題的ImageView(需要被固定爲16:9)是PercentFrameLayout纏繞並有上設置的兩個屬性ImageView,你可能沒有見過的:

app:layout_widthPercent="100%" 
app:layout_aspectRatio="178%" 

所以(1)您需要定義尺寸(寬度或高度)之一,爲我們的問題ImageView領先尺寸。在這種情況下,ImageView將垂直擴展到它的最大寬度(如android:layout_width="match_parent") (2)您需要設置百分比(因此是庫的名稱)的縱橫比,在這種情況下爲178%(16/9 = 1.77777777778或更簡單地將1.78:1或178%)。

閱讀有關百分比支持庫here的更多信息。

1

以上的答案並沒有爲我工作,我發現了這一點,並努力:

public class AspectRatioImageView extends ImageView { 
    // NOTE: These must be kept in sync with the AspectRatioImageView attributes in attrs.xml. 
    public static final int MEASUREMENT_WIDTH = 0; 
    public static final int MEASUREMENT_HEIGHT = 1; 

    private static final float DEFAULT_ASPECT_RATIO = 1f; 
    private static final boolean DEFAULT_ASPECT_RATIO_ENABLED = false; 
    private static final int DEFAULT_DOMINANT_MEASUREMENT = MEASUREMENT_WIDTH; 

    private float aspectRatio; 
    private boolean aspectRatioEnabled; 
    private int dominantMeasurement; 

    public AspectRatioImageView(Context context) { 
    this(context, null); 
    } 

    public AspectRatioImageView(Context context, AttributeSet attrs) { 
    super(context, attrs); 

    TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AspectRatioImageView); 
    aspectRatio = a.getFloat(R.styleable.AspectRatioImageView_aspectRatio, DEFAULT_ASPECT_RATIO); 
    aspectRatioEnabled = a.getBoolean(R.styleable.AspectRatioImageView_aspectRatioEnabled, 
     DEFAULT_ASPECT_RATIO_ENABLED); 
    dominantMeasurement = a.getInt(R.styleable.AspectRatioImageView_dominantMeasurement, 
     DEFAULT_DOMINANT_MEASUREMENT); 
    a.recycle(); 
    } 

    @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
    super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
    if (!aspectRatioEnabled) return; 

    int newWidth; 
    int newHeight; 
    switch (dominantMeasurement) { 
     case MEASUREMENT_WIDTH: 
     newWidth = getMeasuredWidth(); 
     newHeight = (int) (newWidth/aspectRatio); 
     break; 

     case MEASUREMENT_HEIGHT: 
     newHeight = getMeasuredHeight(); 
     newWidth = (int) (newHeight * aspectRatio); 
     break; 

     default: 
     throw new IllegalStateException("Unknown measurement with ID " + dominantMeasurement); 
    } 

    setMeasuredDimension(newWidth, newHeight); 
    } 

    /** Get the aspect ratio for this image view. */ 
    public float getAspectRatio() { 
    return aspectRatio; 
    } 

    /** Set the aspect ratio for this image view. This will update the view instantly. */ 
    public void setAspectRatio(float aspectRatio) { 
    this.aspectRatio = aspectRatio; 
    if (aspectRatioEnabled) { 
     requestLayout(); 
    } 
    } 

    /** Get whether or not forcing the aspect ratio is enabled. */ 
    public boolean getAspectRatioEnabled() { 
    return aspectRatioEnabled; 
    } 

    /** set whether or not forcing the aspect ratio is enabled. This will re-layout the view. */ 
    public void setAspectRatioEnabled(boolean aspectRatioEnabled) { 
    this.aspectRatioEnabled = aspectRatioEnabled; 
    requestLayout(); 
    } 

    /** Get the dominant measurement for the aspect ratio. */ 
    public int getDominantMeasurement() { 
    return dominantMeasurement; 
    } 

    /** 
    * Set the dominant measurement for the aspect ratio. 
    * 
    * @see #MEASUREMENT_WIDTH 
    * @see #MEASUREMENT_HEIGHT 
    */ 
    public void setDominantMeasurement(int dominantMeasurement) { 
    if (dominantMeasurement != MEASUREMENT_HEIGHT && dominantMeasurement != MEASUREMENT_WIDTH) { 
     throw new IllegalArgumentException("Invalid measurement type."); 
    } 
    this.dominantMeasurement = dominantMeasurement; 
    requestLayout(); 
    } 
} 

注:一個辛博爾*更改爲/(讀取源的註釋) 這在/values/attrs.xml

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
    <declare-styleable name="AspectRatioImageView"> 
     <attr name="aspectRatio" format="float" /> 
     <attr name="aspectRatioEnabled" format="boolean" /> 
     <attr name="dominantMeasurement"> 
      <enum name="width" value="0" /> 
      <enum name="height" value="1" /> 
     </attr> 
    </declare-styleable> 
</resources> 

然後你就可以在你的佈局(的aspectRatio =寬/高)用這樣的方式10

Source

9

由於PercentFrameLayoutPercentRelativeLayout是在API層面26.0.0過時了,我建議你考慮使用的ConstraintLayout保持比例16:9的ImageViewConstraintLayout是構建適用於Android平臺的響應式UI的強大工具,您可以在這裏找到更多詳細信息Build a Responsive UI with ConstraintLayout

這裏的例子,如何建立你的ImageView到ConstraintLayout保持16:9比例:

<android.support.constraint.ConstraintLayout 
    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="match_parent"> 

    <ImageView 
     android:id="@+id/imageView" 
     android:layout_width="0dp" 
     android:layout_height="0dp" 
     android:layout_marginEnd="0dp" 
     android:layout_marginStart="0dp" 
     android:layout_marginTop="0dp" 
     app:srcCompat="@mipmap/ic_launcher" 
     app:layout_constraintDimensionRatio="H,16:9" 
     app:layout_constraintStart_toStartOf="parent" 
     app:layout_constraintEnd_toEndOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

</android.support.constraint.ConstraintLayout> 

不要忘了constraint-layout依賴添加到您的模塊的build.gradle文件

implementation "com.android.support.constraint:constraint-layout:1.0.2" 

或者不是編輯XML文件,直接在佈局編輯器中編輯佈局:

Layout Editor