74

I have a few ImageViews inside a LinearLayout. I need to scale down the ImageViews so that they maintain their aspect ratios whilst fitting inside the LinearLayout vertically. Horizontally, I just need them to be adjacent to each other.

I've made a simplified test bed for this which nests weighted Layouts so that I have a wide, but not very tall, LinearLayout for the ImageViews -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent">
    <LinearLayout android:id="@+id/linearLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="5">
        <LinearLayout android:id="@+id/linearLayout3" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1">
            <ImageView android:id="@+id/imageView1" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/test_image" android:scaleType="fitStart"></ImageView>
            <ImageView android:id="@+id/imageView2" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/test_image" android:scaleType="fitStart"></ImageView>
        </LinearLayout>
        <LinearLayout android:id="@+id/linearLayout4" android:layout_height="fill_parent" android:layout_width="fill_parent" android:layout_weight="1"></LinearLayout>
    </LinearLayout>
    <LinearLayout android:id="@+id/linearLayout2" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"></LinearLayout>
</LinearLayout>

(In the Eclipse layout editor the images are clipped vertically and not scaled at all - but that's just one of those idiosyncrasies that we learn to love)

When run on hardware the images are scaled to the correct height whilst preserving their aspect ratio. My problem is that they are not next to each other. The height of each ImageView correctly matches the height of the LinearLayout. The width of each ImageView is the width of the unscaled image - the actual scaled down images appearing at the left side of their ImageViews. Because of this, I'm getting a large gap between the images.

Ideally I would like to manage this through XML though, if this is not possible, I understand that using a custom view may be the best solution.

I tried creating an IconView (extends ImageView) class which overrides onMeasure so that I could create image views of the necessary size by scaling the width depending on the height. But the parentWidth and parentHeight being passed into the function were the dimensions of the screen and not of the LinearLayout container.

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
  int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
  // Calculations followed by calls to setMeasuredDimension, setLayoutParams
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

So my questions are -

1) Can I amend the XML in some way to make it do what I need?

2) How do I make my custom class get the height of the LinearLayout so that I can calculate the necessary width for the custom images?

Thanks if you've managed to read this far. Even more thanks if you can point me in the direction of a solution!

Rok
  • 2,568
  • 4
  • 26
  • 28
  • 1
    Thanks a lot, I had a similar problem: All I wanted was a picture on the top of an app, using the full width. For some unknown reasons, the imageView was nearly double as high as the image itself, blocking off valuable screen space. Thanks to addding `android:adjustViewBounds="true"` the height adjusted to the image – dave Jul 08 '11 at 12:57
  • @dave It's strange that `android::adjustViewBounds` isn't set to true by default. I'm glad your problem is sorted now. – Rok Jul 09 '11 at 07:57

4 Answers4

271

What about changing your ImageViews to use android:layout_height="fill_parent"?

Edit - took me a while to find, but looking at the source helped me pinpoint adjustViewBounds. You might want to try adding android:adjustViewBounds="true" to your ImageViews. Surprisingly, this defaults to false.

Matthew
  • 44,826
  • 10
  • 98
  • 87
  • 7
    Changing the layout_height to fill_parent made no difference but setting adjustViewBounds to true did the trick! I'm amazed I've done so much work with the various views and somehow managed to not notice that parameter! Thank you :) – Rok Mar 18 '11 at 17:13
  • 2
    Me too. I had assumed that it would default to true, but somehow never ran into this issue. – Matthew Mar 18 '11 at 17:15
  • 1
    I really ask myself, why "false" is the default value for that important setting. @MatthewWillis you made my day ;) Thanks a lot. – Mario Fraiß Jan 13 '13 at 18:15
  • It's almost 2015 and I didn't know about this adjustViewBounds="true" trick (sigh). Why this is not true by default! I was doing a lot of yakshaving with an ImageView that didn't seem to respect layout weight in some devices... until I found this answer. Saved my day! – Jose_GD Dec 05 '14 at 20:56
12

Strangely android:layout_height="fill_parent" and android:adjustViewBounds="true" didn't help. The problem I had is image was getting displayed, but with block row on top and black row on bottom of image. Setting scale type to "centerCrop" helped me. I guess, the reason being my image size was small.

Chad Bingham
  • 32,650
  • 19
  • 86
  • 115
user754657
  • 388
  • 3
  • 14
6

I had similar problem and my solution was to set android:scaleType="fitEnd" attribute of ImageView in XML layout file.

MichK
  • 3,202
  • 3
  • 29
  • 33
1

Yes, my solution for this, was:

android:scaleType="fitXY"
pilladooo
  • 713
  • 6
  • 10