Search code examples
androiddialogimageviewscale

How to scale image to maximum size in a dialog-style activity


I have an activity which uses android:theme="@android:style/Theme.Dialog". The activity contains an ImageView which can show images of different dimensions. The ImageView should scale the Image so that it entirely fits into the window, at least on axes fits entirely and maintains the original aspect ratio. The size of the dialog should only be as large as the ImageView (plus its border width).

I tried the following but the dialog window always uses the whole available space:

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/imageParent"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dip">
    <ProgressBar
        android:id="@android:id/progress"
        android:layout_width="40dip"
        android:layout_height="40dip"
        android:layout_centerInParent="true"
        android:visibility="gone"
        style="@android:attr/progressBarStyleSmallTitle"/>
    <ImageView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:id="@+id/image"/>
</RelativeLayout>

Solution

  • I found a Solution by myself but I'm not totally sure if it does the correct thing at any given situation. I created a subclass of ImageView (CustomImageView) and defined the onMeasure() method as following:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            int measureHeight = View.MeasureSpec.getSize(heightMeasureSpec);
            int measureWidth = View.MeasureSpec.getSize(widthMeasureSpec);
    
            int resultWidth = measureWidth;
            float scaleFactor = (float)resultWidth / drawable.getMinimumWidth();
            int resultHeight = (int)(scaleFactor * drawable.getMinimumHeight());
    
            if (resultHeight > measureHeight) {
                resultHeight = measureHeight;
                scaleFactor = (float)resultHeight / drawable.getMinimumHeight();
                resultWidth = (int)(scaleFactor * drawable.getMinimumWidth());
            }
    
            setMeasuredDimension(resultWidth, resultHeight);
        } else {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    
    }
    

    My Layout looks as following now:

    <?xml version="1.0" encoding="UTF-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/imageParent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="10dip">
        <ProgressBar
            android:id="@android:id/progress"
            android:layout_width="40dip"
            android:layout_height="40dip"
            android:layout_centerInParent="true"
            style="@android:attr/progressBarStyleSmallTitle"
            android:visibility="gone"/>
        <com.example.CustomImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:scaleType="fitCenter"
            android:id="@+id/image"/>
    </RelativeLayout>