15

I have an ImageView which I want to always be the same size. If the image is smaller than the view, I'd like it to be centred in the view. If the Image is larger than the view then I'd like it scaled down - with aspect ratio preserved.

I've had several attempts at this myself - the latest of which is:

<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">
  <ImageView android:id="@+id/itemImage" android:layout_width="100dp"
            android:layout_height="100dp" android:scaleType="fitCenter"
            android:adjustViewBounds="true" android:gravity="center" android:padding="10px" />
  <TextView android:id="@+id/currentLentItem" android:layout_width="wrap_content"
                android:layout_height="wrap_content" android:padding="10px"/>
</LinearLayout>

What am I missing here?

Paul Hunnisett
  • 898
  • 1
  • 17
  • 36

2 Answers2

11

If the image is larger than the view, then you could scale it using:

android:scaleType="fitXY" 

That won't give you what you want if the image is smaller. Perhaps you could detect that in runtime and change the scaleType programmatically.

kgiannakakis
  • 103,016
  • 27
  • 158
  • 194
11

Try using the scale type centerInside, like below:

<?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >
    <ImageView
        android:id="@+id/itemImage"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_alignParentRight="true"
        android:scaleType="centerInside"
        android:gravity="right|center_vertical"
        android:padding="10px"
        />
    <TextView
        android:id="@+id/currentLentItem"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_toLeftOf="@id/list_image"
        android:padding="10px"
        />
</RelativeLayout>

This causes the image to scale down only if larger than the layout, and it will scale proportionally as well (whereas fitXY scales without regard to aspect ratio). It will also center the image if smaller.

EDIT: I've updated the example for something like you're wanting. Here's the gist of what changed:

• ImageView gravity changed to right|center_vertical. Since you want them to align on the right, using this gravity will allow that even if they are portrait orientation images.

• ImageView aligned to the right of the RelativeLayout

• RelativeLayout set to wrap_content since it's to be used for a ListView.

• TextView added, aligned to the parent's left, with its right edge defined by the left edge of itemImage.

Kevin Coppock
  • 133,643
  • 45
  • 263
  • 274
  • Thanks for that - it does look better. The View still doesn't seem to be a fixed size, though. As you can see from my example above, the ImageView is next to a TextView - and this is displayed in a ListView. I want the right edge of the ImageViews to be lined up with each other so that everything looks neat and uniform... – Paul Hunnisett Nov 17 '10 at 09:51
  • Paul, I've added an updated example that you can try; this should get you closer to what you're looking for. – Kevin Coppock Nov 17 '10 at 14:20
  • Thanks. The ImageViews are still not the same size, though. I need them all to be exactly the same width. I would have thought that setting layout_width would do this - but it obviously doesn't... – Paul Hunnisett Nov 17 '10 at 16:43
  • 1
    Your ImageViews are the same size, it's the content inside them that changes. If they all must be the same width, you will need to use something like centerCrop or fitCenter instead for your scaletype. From what I understood you didn't want them scaled if they were smaller than 100dp, but you should use fitCenter if you want them to scale to exactly 100dp regardless. Where this becomes an issue is when you have images of portrait orientation. FitCenter will work, but the height will be 100dp, the width will be proportionately smaller...(cont) – Kevin Coppock Nov 17 '10 at 18:34
  • 1
    This is when you may want to use centerCrop (I'm pretty sure centerCrop is the one I'm thinking of). It will make the smallest side fit the container, but your longest side will be cropped off to fit within the container. Basically, if you won't have portrait oriented images, fitCenter will do the trick. If you do have portrait images, you'll either have to crop, or have varying heights. – Kevin Coppock Nov 17 '10 at 18:36
  • If you go to http://www.monkeypower.co.uk/screenie.png you can see an screenshot of how it looks now. You can see that the TextViews on the bottom 3 are wider than on the top two. What I want is for all the views to line up nicely with each other... I tried centerCrop - in fact, that's what is in the screenshot. – Paul Hunnisett Nov 18 '10 at 17:46