I have an image which is smaller than the container I would like it to fit inside of. I would like the image to stretch, keeping it's aspect ratio, to it's largest possible size.
To illustrate this problem:
<ImageView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="@drawable/thumbnail"
android:scaleType="fitXY"
android:adjustViewBounds="true"/>
The ImageView
above would be stretched to fill the width of the container. The @drawable
it contained would also stretch along the x axis to fit the width of ImageView
which is perfect. The problem however is that the dimension labelled wrap_content
, in this case height, remains the same size as the @drawable
s initial height.
I have read the documentation regarding ScaleType here and can't find the answer there.
The following image describes the above code:
Current behaviour Desired Behaviour
Edit
An ImageView
given scaleType="fitCenter"
will accurately expand/shrink the @drawable
inside of it to grow as large as possible while retaining it's aspect ratio.
The ImageView
s dimensions are defined before the @drawable
is scaled in any way. The ImageView
dimensions are not effected by scaling of it's contained @drawable
.
In the CSS for the <div>, add a percentage value for padding-bottom and set the position to relative, this will maintain the aspect ratio of the container. The value of the padding determines the aspect ratio. ie 56.25% = 16:9.
What if our image needs to be limited to the width of a parent element? In that situation we can use CSS max-width or width to fit the image. Use max-width: 100% to limit the size but allow smaller image sizes, use width: 100% to always scale the image to fit the parent container width.
When scaling your image, it's crucial to maintain the ratio of width to height, known as aspect ratio, so it doesn't end up stretched or warped. If you need a specific width and height, you may need a mixture of resizing and cropping to get the desired result.
XML
The only solution to this in XML is to use "match_parent"
or a discrete maximum value instead of "wrap_content"
where possible. This will ensure the ImageView
is the correct size, which will then meaning adding scaleType="fitCenter"
will ensure the @drawable
will then scale correctly.
Programatically
It's ugly, but you can resize the ImageView after it's dimensions have been given discrete values:
final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail);
ViewTreeObserver thumbnailViewVto = thumbnailView.getViewTreeObserver();
thumbnailViewVto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
private boolean changed = false;
@Override
public void onGlobalLayout() {
if(!changed) {
Drawable image = getResources().getDrawable(R.drawable.thumbnail);
float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight();
int height = thumbnailView.getHeight();
thumbnailView.setLayoutParams(
new LayoutParams(
(int) (height * heighToWidthRatio), height));
changed = true;
}
}
});
EDIT
final ImageView thumbnailView = (ImageView) toReturn.findViewById(R.id.thumbnail);
thumbnailView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Remove the GlobalOnLayout Listener so it only fires once.
thumbnailView.getViewTreeObserver().removeGlobalOnLayoutListener(this)
// Find the images Height to Width ratio
Drawable image = getResources().getDrawable(R.drawable.thumbnail);
float heighToWidthRatio = image.getIntrinsicWidth()/image.getIntrinsicHeight();
// Use this ratio to discover the ratio of the ImageView to allow it to perfectly contain the image.
int height = thumbnailView.getHeight();
thumbnailView.setLayoutParams(new LayoutParams(
(int) (height * heighToWidthRatio), height));
}
});
Looks like you want fitCenter, which uses Matrix.ScaleToFit CENTER.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With