88

I download image and set it as a screen background dynamically using Imageview. I have tried ScaleType, to scale the image.

If image height is larger than width then ScaleTypes fitStart, fitEnd and fitCenter don't work. Android scale down the photo and fit it based on the height, but I see some extra blank space as part of the width.

I want to scale down the photo based on the width so that it fits the width and I don't care if there's some extra blank space as part of the height or if height is too long it is fine if it's going out of the view(if that's possible?).

ScaleType.XY scale the photo and fit everything in the ImageView and doesn't care about image height/weight ratio.

<ImageView 
                android:id="@+id/background"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:adjustViewBounds="true"
                android:scaleType="fitStart"
            />
Sharjeel
  • 15,588
  • 14
  • 58
  • 89

7 Answers7

210

I ended up using this code:

<ImageView 
                android:id="@+id/background"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:adjustViewBounds="true"
                android:scaleType="centerCrop"
                android:src="@drawable/name"
            />

Make sure you set the image using src instead of background.

Sharjeel
  • 15,588
  • 14
  • 58
  • 89
82

android:adjustViewBounds="true" does the job!

ViliusK
  • 11,345
  • 4
  • 67
  • 71
14

This elegant solution found here will work like a charm for you.

Basically you just have to create a small class that extends ImageView and simply override the onMeasure method to adjust the width and height as you want. Here it scales to fit width by using:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);
    int height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth();
    setMeasuredDimension(width, height);
}

You would use this special ImageView like this:

<your.activity.package.AspectRatioImageView 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="center_vertical"
    android:src="@drawable/test" />
Community
  • 1
  • 1
Michel-F. Portzert
  • 1,785
  • 13
  • 16
  • I have a ListView containing images downloaded on the fly. So adapter returns a layout with ImageView which size can change dynamically. This was the only approach that worked for me. Thanks. – Dennis K Mar 19 '14 at 06:03
  • this isn't elegant at all, this is pretty hacky. look at the accepted answer. – mpellegr Nov 16 '18 at 21:14
9

There is a simple method if you simply want to fill the width of screen and have height proportional (and know the ratio of the image) you can do this in OnCreate():

setContentView(R.layout.truppview_activity);
trupImage = (ImageView) findViewById(R.id.trupImage);

Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics();
display.getMetrics(outMetrics);
float scWidth = outMetrics.widthPixels;
trupImage.getLayoutParams().width = (int) scWidth;
trupImage.getLayoutParams().height = (int) (scWidth * 0.6f);

Where 0.6 is the ratio adjustment (you could also calc automatically of course if you know the w & h of image).

PS:
Here is the XML side:

  <ImageView
        android:id="@+id/trupImage"
        android:layout_width="match_parent"
        android:background="@color/orange"
        android:layout_height="match_parent" 
        android:adjustViewBounds="true" 
        android:scaleType="fitCenter" />
Josh Kovach
  • 7,679
  • 3
  • 45
  • 62
Dan Harvey
  • 798
  • 1
  • 10
  • 23
8

if you want to fit the image whole parent block
it will stretch the image

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY" 

And if you want to fit image whole parent with original ratio of image
it will crop out some part of image

        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
SK. Fuad
  • 371
  • 4
  • 9
6

This works for me.

Create a class extends ImageView

    package com.yourdomain.utils;

    import android.content.Context;
    import android.graphics.drawable.Drawable;
    import android.util.AttributeSet;
    import android.widget.ImageView;

    public class ResizableImageView extends ImageView {

        public ResizableImageView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }

        @Override 
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            Drawable d = getDrawable();

            if (d != null) {
                int width = MeasureSpec.getSize(widthMeasureSpec);
                int height = (int) Math.ceil((float) width * (float) d.getIntrinsicHeight() / (float) d.getIntrinsicWidth());
                setMeasuredDimension(width, height);
            } else {
                super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            }
        }
    }

In xml use the following instead of ImageView

    <com.yourdomain.utils.ResizableImageView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/test" />
muetzenflo
  • 5,653
  • 4
  • 41
  • 82
Thomas VJ
  • 61
  • 1
  • 2
1

I think you cant do it only with XML, you need to resize yourself, the bitmap

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();

        try {
            ((ImageView) findViewById(R.id.background))
                    .setImageBitmap(ShrinkBitmap(width));
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

then

private Bitmap ShrinkBitmap(int width)
        throws FileNotFoundException {

    BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
    bmpFactoryOptions.inJustDecodeBounds = true;
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.img, bmpFactoryOptions);
    int widthRatio = (int) android.util.FloatMath
            .ceil(bmpFactoryOptions.outWidth / (float) width);


    bmpFactoryOptions.inSampleSize = widthRatio;



    if (bmpFactoryOptions.inSampleSize <= 0)
        bmpFactoryOptions.inSampleSize = 0;
    bmpFactoryOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;
    bmpFactoryOptions.inJustDecodeBounds = false;
    bitmap = BitmapFactory.decodeResource(getResources(),
            R.drawable.img, bmpFactoryOptions);
    return bitmap;

}

And the layout

 <ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/background"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
  />