Often asked, never answered (at least not in a reproducible way).
I have an image view with an image that is smaller than the view. I want to scale the image to the width of the screen and adjust the height of the ImageView to reflect the proportionally correct height of the image.
<ImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
This results in the image centered at its original size (smaller then the screen width) with margins at the side. No good.
So I added
android:adjustViewBounds="true"
Same effect, no good. I added
android:scaleType="centerInside"
Same effect, no good. I changed centerInside
to fitCenter
. Same effect, no good. I changed centerInside
to centerCrop
.
android:scaleType="centerCrop"
Now, finally, the image is scaled to the width of the screen - but cropped at top and bottom! So I changed centerCrop
to fitXY
.
android:scaleType="fitXY"
Now the image is scaled to the width of the screen but not scaled on the y-axis, resulting in a distorted image.
Removing android:adjustViewBounds="true"
has no effect. Adding an android:layout_gravity
, as suggested elsewhere, has again no effect.
I have tried other combinations -- to no avail. So, please does anyone know:
How do you set up the XML of an ImageView to fill the width of the screen, scale a smaller image to fill the entire view, displaying the image with its aspect ratio without distortion or cropping?
EDIT: I also tried setting an arbitrary numeric height. This only has an effect with the centerCrop
setting. It will distort the image vertically according to the view height.
I have solved this by creating a java-class that you include in your layout-file:
public class DynamicImageView extends ImageView {
public DynamicImageView(final Context context, final AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final Drawable d = this.getDrawable();
if (d != null) {
// ceil not round - avoid thin vertical gaps along the left/right edges
final int width = MeasureSpec.getSize(widthMeasureSpec);
final int height = (int) Math.ceil(width * (float) d.getIntrinsicHeight() / d.getIntrinsicWidth());
this.setMeasuredDimension(width, height);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
Now, you use this by added your class to your layout-file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<my.package.name.DynamicImageView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scaleType="centerCrop"
android:src="@drawable/about_image" />
</RelativeLayout>