49

I have a square image (though this problem also applies to rectangular images). I want to display the image as large as possible, stretching them if necessary, to fill their parents, while still maintaining the aspect ratio. The image is smaller than the ImageView. The problem is, I can't stretch the image and "match" the height and width of the ImageView.

This is my XML layout file:

<?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"
                android:padding="10dp">

    <ImageView android:id="@+id/image"
               android:layout_width="fill_parent"
               android:layout_height="fill_parent"
               android:adjustViewBounds="true"
               android:scaleType="fitCenter"
               android:layout_marginTop="10dp"/>

    <TextView android:id="@+id/name"
              android:layout_below="@id/image"
              android:layout_alignLeft="@id/image"
              android:layout_marginTop="20dp"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textSize="18dp"/>

    <TextView android:id="@+id/name2"
              android:layout_below="@id/name"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textSize="14dp"/>


</RelativeLayout>

I have used many combinations of fill_parent, wrap_content with multiple scaleTypes: fitCenter, fitStart, fitEnd, centerInside, and they all draw the images in the right aspect ratio, but none of them actually scale the images up and the ImageView itself, resulting in either the TextViews get pushed all the way down off the screen, blank spaces inside the ImageView, image not scaled, or image cropped.

I can't quite figure the right combination for this.

Onik
  • 19,396
  • 14
  • 68
  • 91
garbagecollector
  • 3,731
  • 5
  • 32
  • 44
  • try the answer given here: http://stackoverflow.com/questions/5355130/android-imageview-size-not-scaling-with-source-image – FoamyGuy May 31 '12 at 01:53
  • 1
    @Tim: I already set `adjustViewBounds=true`. It somehow did not resize the ImageView bounds. – garbagecollector May 31 '12 at 02:00
  • Do you have only one image or multiple? Have you thought of using a `ScrollView`? Is your image height bigger than the screen height? If so, how do you want your layout to look? Your `TextView` `name`, is it supposed to be to the left or below of the image? If you want all 3 views to fit your screen, they should all have `android:layout_height="wrap_content"`. – slybloty May 31 '12 at 14:08
  • @slybloty I have multiple, but I'm displaying one image. I should have worded this question better. It is displaying one image. – garbagecollector May 31 '12 at 19:06
  • Have you tried `android:scaleType="fitXY"`? It stretches the image to match the width and height you assign (i.e, it doesn't respect aspect ratio). – Sufian Apr 30 '13 at 12:17
  • possible duplicate of [ImageView adjustViewBounds not working](http://stackoverflow.com/questions/7719617/imageview-adjustviewbounds-not-working) – aleb Jul 31 '13 at 17:37
  • you can try this response: http://stackoverflow.com/questions/5554682/android-imageview-adjusting-parents-height-and-fitting-width/12283909#12283909 – OriolJ Oct 09 '13 at 09:28

7 Answers7

115

These:

android:layout_height="wrap_content"
android:scaleType="fitStart"
android:adjustViewBounds="true"

should resize the image and change the size of the bounds to fit the new image size. If it does not do that on your device post the image you are using and what device you are testing on.

FoamyGuy
  • 46,603
  • 18
  • 125
  • 156
  • 3
    Does not work. I cannot post the images because they are proprietary, but they are just standard 128x128 PNGs. This also occuring on the emulator. So it's not device specific issues. These images are smaller than the ImageView. I think that's where the problem is. – garbagecollector May 31 '12 at 19:08
  • adjustViewBounds is not enough, it "will not increase the size of the ImageView beyond the natural dimensions of the drawable": http://stackoverflow.com/a/7732684/804479 – aleb Aug 01 '13 at 10:30
  • I think the solution is to use scaleType="centerCrop", if you can accept the image to be cropped... – Christophe Fondacci Apr 06 '14 at 03:57
  • Worked perfectly for me. Thanks! – Hristova May 15 '15 at 11:23
  • @Foam Guy will this work if i m getting images from server ? – Erum Sep 01 '15 at 08:58
  • @Erum shouldn't matter where the image came from. – FoamyGuy Sep 01 '15 at 23:56
  • first time when I used this solution in recyclerview images it is working.Then I have uploaded new image and checked all images in recyclerview it is now working.Anyone know why it is happening? – Stephen Oct 12 '16 at 09:51
  • I know we aren't supposed to add these kind of comments but... You rock! – Jona Jan 31 '17 at 23:20
49

Use this code : android:scaleType="fitXY"

For more details about image scaling, look what's motioned in this article here

Summary:

  • center

Center the image in the view, but perform no scaling

enter image description here

  • centerCrop

Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or larger than the corresponding dimension of the view (minus padding). The image is then centered in the view

enter image description here

  • centerInside

Scale the image uniformly (maintain the image's aspect ratio) so that both dimensions (width and height) of the image will be equal to or less than the corresponding dimension of the view (minus padding)

enter image description here

  • fitCenter

enter image description here

  • fitEnd

enter image description here

  • fitStart

enter image description here

  • fitXY

enter image description here

  • matrix

Scale using the image matrix when drawing

enter image description here

more details here new article

Context
  • 1,873
  • 1
  • 20
  • 24
22

This xml code will work!. If you are specifying that your apps width is always same as the window, then the android:adjustViewBounds="true" will set the height respective to the ration of the image.

        <ImageView
        android:adjustViewBounds="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/screen"/>
Febin Mathew
  • 991
  • 1
  • 11
  • 20
  • May the stackoverflow god bless your soul. I spent a whole day on this, gave up with either a narrow image or one with white sides. Came back this morning and figured "Hey let me google it" @garbagecollector should really accept this answer!! – Иво Недев Aug 30 '18 at 08:21
  • @ИвоНедев stackoverflow god is not blessing me somehow, it's not working. image aspect ratio is not keep. – flankechen Mar 25 '19 at 14:30
13

Use this code with view layout parameters as wrapcontent

android:adjustViewBounds="true"

Hope this it will work.

Akash Patra
  • 768
  • 1
  • 9
  • 20
  • adjustViewBounds is not enough, it "will not increase the size of the ImageView beyond the natural dimensions of the drawable": http://stackoverflow.com/a/7732684/804479 – aleb Aug 01 '13 at 10:29
4

I had the same issue, android:adjustViewBounds not doing its job and having a padding at the top of the image. Into a relative layout that had match_parent values for the width and the height, I had:

   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical" android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@color/transparent">

   <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="fitStart"
    android:adjustViewBounds="true" ...

I changed the Relative layout to a Linear layout with wrap_content values for width and height and now it is ok:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
  • 1
    After many hours of searching I also changed RelativeLayout to LinearLayout. But in my case an ImageView hadn't been shown. – CoolMind Aug 05 '16 at 21:25
  • My ImageView: "" Was inside a Relative layout, the ImageView would deal with it's height correctly but it had extra padding on the left and the right somewhy. After reading this answer and @CoolMind's comment, I tried and changed it into a LinearLayout and poof, the ImageView has no more side padding. I would love to understand this voodoo. – Matan Koby Nov 08 '18 at 10:42
  • @MatanKoby, happy coding! Android has many secrets and dungeons. – CoolMind Nov 08 '18 at 10:48
3

Did you try to adjust it programmaticaly? I think it works really well if you calculate the height of your TextViews and adjust the height and width of the image based on this.

private void adjustImageView()
{
    //Get the display dimensions
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    //TextView name
    TextView name = (TextView) findViewById(R.id.name);
    name.setText("your name text goes here");
    name.measure(0, 0);

    //name TextView height
    int nameH = name.getMeasuredHeight();

    //TextView name2
    TextView name2 = (TextView) findViewById(R.id.name2);
    name2.setText("your name2 text goes here");
    name2.measure(0, 0);

    //name2 TextView height
    int name2H = name2.getMeasuredHeight();

    //Original image
    Bitmap imageOriginal = BitmapFactory.decodeResource(getResources(), R.drawable.image);

    //Width/Height ratio of your image
    float imageOriginalWidthHeightRatio = (float) imageOriginal.getWidth() / (float) imageOriginal.getHeight();

    //Calculate the new width and height of the image to display 
    int imageToShowHeight = metrics.heightPixels - nameH - name2H;
    int imageToShowWidth = (int) (imageOriginalWidthHeightRatio * imageToShowHeight);

    //Adjust the image width and height if bigger than screen
    if(imageToShowWidth > metrics.widthPixels)
    {
        imageToShowWidth = metrics.widthPixels;
        imageToShowHeight = (int) (imageToShowWidth / imageOriginalWidthHeightRatio);
    }

    //Create the new image to be shown using the new dimensions 
    Bitmap imageToShow = Bitmap.createScaledBitmap(imageOriginal, imageToShowWidth, imageToShowHeight, true);

    //Show the image in the ImageView
    ImageView image = (ImageView) findViewById(R.id.image);
    image.setImageBitmap(imageToShow);
}
slybloty
  • 6,346
  • 6
  • 49
  • 70
0

Set android:layout_height="wrap_content" in imageview. To create an image with width equals screen width, and height proportionally set according to aspect ratio, do the following. Here I mention how to load image to imageview from url.

Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

                        // creating the image that maintain aspect ratio with width of image is set to screenwidth.
                        int width = imageView.getMeasuredWidth();
                        int diw = resource.getWidth();
                        if (diw > 0) {
                            int height = 0;
                            height = width * resource.getHeight() / diw;
                            resource = Bitmap.createScaledBitmap(resource, width, height, false);
                        }
                                              imageView.setImageBitmap(resource);
                    }
                });

Hope this helps.

Fathima km
  • 2,539
  • 3
  • 18
  • 26