Android ImageView-16:9

Android ImageView-16:9,android,bitmap,android-imageview,aspect-ratio,Android,Bitmap,Android Imageview,Aspect Ratio,我需要将位图设置为ImageView以保持16:9的比例。你有什么建议吗?主要的解决方案可能是在测量自定义ImageView时使用覆盖方法,但如何使用?编辑2019年3月1日:经过这么长时间,我强烈建议使用@Eugene Brusov下面介绍的ConstraintLayout。我个人永远不会使用通过覆盖onMeasure进行数学运算的图像视图 编辑2018年3月29日:我下面的答案可能很简单,但可能太原始了。如果你想利用Google的ConstraintLayout提供的内容,请跟随或向下滚动查

我需要将位图设置为ImageView以保持16:9的比例。你有什么建议吗?主要的解决方案可能是在测量自定义ImageView时使用覆盖方法,但如何使用?

编辑2019年3月1日:经过这么长时间,我强烈建议使用@Eugene Brusov下面介绍的
ConstraintLayout
。我个人永远不会使用通过覆盖onMeasure进行数学运算的图像视图

编辑2018年3月29日:我下面的答案可能很简单,但可能太原始了。如果你想利用Google的ConstraintLayout提供的内容,请跟随或向下滚动查看@Eugene Brusov的答案

旧答案:

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"/>

编辑:谷歌已经正式反对从API 26开始的百分比支持库,你应该尽快放弃它。

将大小设置为一个比率 如果至少有一个视图尺寸设置为“匹配约束”(0dp),则可以将视图大小设置为16:9等比率。要启用该比率,请单击“切换纵横比约束”(图10中的详图索引1),然后在显示的输入中输入宽高比

如果“宽度”和“高度”都设置为匹配约束,则可以单击“切换纵横比约束”,以选择基于另一个约束的比例的标注。视图检查器通过用实线连接相应的边来指示设置为比率的对象

例如,如果将两侧设置为“匹配约束”,请单击两次“切换纵横比约束”,将宽度设置为高度的比率。现在,整个尺寸由视图的高度决定(可以以任何方式定义),如下图所示:

更多信息请点击此处:


在支持库中有一个名为
PercentFrameLayout
PercentRelativeLayout
的东西

<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>
因此(1)您需要定义一个维度(宽度或高度)作为所讨论的
ImageView
的主要维度。在这种情况下,
ImageView
将垂直扩展到其最大宽度(如
android:layout\u width=“match\u parent”
) (2)您需要以百分比形式设置纵横比(因此库的名称),在本例中为178%(16/9=1.778或更高,简单地说是1.78:1或178%)


请阅读有关百分比支持库的更多信息。

以上答案对我不适用,我找到了这个答案并成功:

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();
  }
}
注意:一个simbol
*
更改为
/
(阅读源代码中的注释) 在您的
/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>


>代码> %FrAMELayayOut和%RealEffelayOut/<代码>在API级别22.0.0中被剔除,我建议您考虑使用<代码>约束布局>代码>以保持<16:9为您的代码> IVIEVIEW 。code>ConstraintLayout
是为Android平台构建响应式用户界面的强大工具,您可以在这里找到更多详细信息

以下是如何将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>

或者直接在布局编辑器中编辑布局,而不是编辑XML文件:


非常感谢,这是未来自定义视图的好例子
<com.yourpackage.ui.classes.AspectRatioImageView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:scaleType="centerCrop"
        app:aspectRatio="1.78"
        app:aspectRatioEnabled="true"
        app:dominantMeasurement="width" />
<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>
implementation "com.android.support.constraint:constraint-layout:1.0.2"