Android ImageView - 16:9
Since PercentFrameLayout
and PercentRelativeLayout
were deprecated in API level 26.0.0, I'd suggest you to consider using of ConstraintLayout
to keep ratio 16:9 for your ImageView
. ConstraintLayout
is really powerful tool to build Responsive UI for Android platform, you can find more details here Build a Responsive UI with ConstraintLayout.
Here is the example how to build your ImageView into ConstraintLayout to keep 16:9 ratio:
<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>
Don't forget to add constraint-layout
dependency to your module's build.gradle
file
implementation "com.android.support.constraint:constraint-layout:1.0.2"
Or instead of editing your XML file, edit your layout directly in Layout Editor:
EDIT 01/03/2019: After all this time, I strongly recommend using ConstraintLayout
that @Eugene Brusov introduced below. I personally would never use my image view that does Math by overriding onMeasure.
EDIT 03/29/2018: My answer below may be simple, but may be too much of raw answer. If you want to utilize what's already given by Google's ConstraintLayout
, follow this answer or scroll down and see @Eugene Brusov's answer.
Old answer:
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);
}
}
Then in your xml
<path.to.package.CustomImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img"/>
EDIT: Google has officially deprecated the Percent support library starting API 26 and you should move away from it as soon as possible.
Set size as a ratio You can set the view size to a ratio such as 16:9 if at least one of the view dimensions is set to "match constraints" (0dp). To enable the ratio, click Toggle Aspect Ratio Constraint (callout 1 in figure 10), and then enter the width:height ratio in the input that appears.
If both the width and height are set to match constraints, you can click Toggle Aspect Ratio Constraint to select which dimension is based on a ratio of the other. The view inspector indicates which is set as a ratio by connecting the corresponding edges with a solid line.
For example, if you set both sides to "match constraints", click Toggle Aspect Ratio Constraint twice to set the width be a ratio of the height. Now the entire size is dictated by the height of the view (which can be defined in any way) as shown in figure below:
More information here: https://developer.android.com/training/constraint-layout/index.html#adjust-the-view-size
There is something called PercentFrameLayout
and PercentRelativeLayout
in the Support library.
<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>
If you take a closer look at the above layout, you'll see that the ImageView
in question (that needs to be fixed at 16:9) is wrapped around a PercentFrameLayout
and there's two attributes set on the ImageView
that you might not have seen before:
app:layout_widthPercent="100%"
app:layout_aspectRatio="178%"
So (1) you need to define one of the dimensions (either width or height) to be the leading dimension for our ImageView
in question. In this case the ImageView
will expand vertically, to it's maximum width (like android:layout_width="match_parent"
)
And (2) you need to set the aspect ratio in percentage (hence the name of the library) which is in this case 178% (16/9 = 1.77777777778 or more simply put 1.78:1 or 178%).
Read more about the Percent Support Library here.