I want to download an image (of unknown size, but which is always roughly square) and display it so that it fills the screen horizontally, and stretches vertically to maintain the aspect ratio of the image, on any screen size. Here is my (non-working) code. It stretches the image horizontally, but not vertically, so it is squashed...
ImageView mainImageView = new ImageView(context);
mainImageView.setImageBitmap(mainImage); //downloaded from server
mainImageView.setScaleType(ScaleType.FIT_XY);
//mainImageView.setAdjustViewBounds(true);
//with this line enabled, just scales image down
addView(mainImageView,new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
In some cases this magic formula beautifully solves the problem.
For anyone struggling with this coming from another platform, the "size and shape to fit" option is handled beautifully in Android, but it's hard to find.
You typically want this combination:
Then it's automatic and amazing.
If you're an iOS dev, it's utterly amazing how simply you can do "totally dynamic cell heights" in a table view .. err, I mean ListView. Enjoy.
Look there is a far easier solution to your problem:
A very simple solution is to just use the features provided by
RelativeLayout
.Here is the xml that makes it possible with standard Android
Views
:The trick is that you set the
ImageView
to fill the screen but it has to be above the other layouts. This way you achieve everything you need.I just read the source code for
ImageView
and it is basically impossible without using the subclassing solutions in this thread. InImageView.onMeasure
we get to these lines:Where
h
andw
are the dimensions of the image, andp*
is the padding.And then:
So if you have a
layout_height="wrap_content"
it will setwidthSize = w + pleft + pright
, or in other words, the maximum width is equal to the image width.This means that unless you set an exact size, images are NEVER enlarged. I consider this to be a bug, but good luck getting Google to take notice or fix it. Edit: Eating my own words, I submitted a bug report and they say it has been fixed in a future release!
Another solution
Here is another subclassed workaround, but you should (in theory, I haven't really tested it much!) be able to use it anywhere you
ImageView
. To use it setlayout_width="match_parent"
, andlayout_height="wrap_content"
. It is quite a lot more general than the accepted solution too. E.g. you can do fit-to-height as well as fit-to-width.You are setting the ScaleType to ScaleType.FIT_XY. According to the javadocs, this will stretch the image to fit the whole area, changing the aspect ratio if necessary. That would explain the behavior you are seeing.
To get the behavior you want... FIT_CENTER, FIT_START, or FIT_END are close, but if the image is narrower than it is tall, it will not start to fill the width. You could look at how those are implemented though, and you should probably be able to figure out how to adjust it for your purpose.
This working fine as per my requirement
<ImageView android:id="@+id/imgIssue" android:layout_width="fill_parent" android:layout_height="wrap_content" android:adjustViewBounds="true" android:scaleType="fitXY"/>