Java – Extends ImageView to the maximum possible aspect ratio in Android

Extends ImageView to the maximum possible aspect ratio in Android… here is a solution to the problem.

Extends ImageView to the maximum possible aspect ratio in Android

I found a lot of answers on this site, but they didn’t work or only for individual cases. In my case:

  • I want to load an image and display it in an ImageView.
  • The width of the ImageView must be the largest possible width: the parent layout width.
  • The height must be one that allows the image to be rescaled to maintain the aspect ratio.

How to do this? Here’s my layout with ImageView in it (currently I’ve been using fitXY, but images don’t retain the aspect ratio, even with adjustViewBounds:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/layoutPictureGalleryItem"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp"
    android:background="#E0E0DE"
    android:orientation="vertical" >

<ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY"
        tools:ignore="ContentDescription" />

<LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:background="#FFFFFF" >

<TextView
            android:id="@+id/textName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="esto es una prueba para ver cómo queda el layout"
            android:textColor="#000000"
            android:textSize="12sp"
            android:typeface="serif"
            android:padding="2dp" />

<TextView
            android:id="@+id/textDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone"
            android:padding="2dp" />

</LinearLayout>

</LinearLayout>

Solution

Use this widget instead of your ImageView and have the width match the parent:

package com.myapp.widgets;

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)
{
    super(context);
}

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

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

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    Drawable drawable = getDrawable();
    if (drawable != null)
    {
        int width =  MeasureSpec.getSize(widthMeasureSpec);
        int diw = drawable.getIntrinsicWidth();
        if (diw > 0)
        {
            int height = width * drawable.getIntrinsicHeight() / diw;
            setMeasuredDimension(width, height);
        }
        else
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
    else
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}

Related Problems and Solutions