ImageView: fill horizontal maintaining aspect ratio

I need an ImageView scale it image until fill the parent horizontally.

If the imageview background is red, and the rest of the content (below the image) is the green I'm looking for the result shown by the Picture 1 . That result is obtained automatically if the image width is higher than the screen width.

But if is a small picture like in the picture 2. the best result I can get is the picture 3 (setting the ImageView width and height to fill_parent and the scaleType to FitStart

The picture 4 is obtained setting height= wrap_content, width= fill_parent, scaleType= CenterCrop. It should scale vertically for show the entire image, but as the scaleType says it crops it.

Any ideas for getting the picture 1 even if the image is small?

Will grant a bounty of 50 to a working answer

在这里输入图像描述


I found an easy solution that works really good for me. Set width and height as you wish, eg:

android:layout_width="fill_parent"
android:layout_height="wrap_content"

Then you also set this setting:

android:adjustViewBounds="true"

"adjustViewBounds" defaults to false (which I find odd) but setting it makes it easy to fill the image in the imageview.


It's doable without custom classes. This is the result I've gained with small image: 在这里输入图像描述

With large image: 在这里输入图像描述

You have to use RelativeLayout in order for this to work, but you can combine it with LinearLayout to achieve whatever you need. Here is my xml:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fillViewport="true">

    <RelativeLayout 
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >
        <LinearLayout
            android:id="@+id/button_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:layout_alignParentBottom="true"
            >
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
            <Button
                android:text="button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"/>
        </LinearLayout>
        <ImageView 
            android:src="@drawable/cat"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:adjustViewBounds="true"
            android:scaleType="centerCrop"
            android:layout_above="@id/button_container"/>
    </RelativeLayout>
</ScrollView>

The trick is that you set it to fill the screen but it has to be above the other layouts. This way you achieve everything you need.


Try this one :

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ViewGroup;

public class CustomImageView extends android.widget.ImageView {

    public CustomImageView(Context context) {
        super(context);
    }

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

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

    public void fitYUniformly() {
        final Drawable drawable = getDrawable();
        if (drawable == null) return;

        final int dwidth = drawable.getIntrinsicWidth();
        final int dheight = drawable.getIntrinsicHeight();
        if (dwidth == -1 || dheight == -1) return;

        int vheight = this.getHeight();
        float scale = (float) vheight / (float) dheight;

        final int vwidth = (int) (dwidth * scale);
        scale(scale, vwidth, vheight);
    }

    public void fitXUniformly(int parentWidth) {
        final Drawable drawable = getDrawable();
        if (drawable == null) return;

        final int dwidth = drawable.getIntrinsicWidth();
        final int dheight = drawable.getIntrinsicHeight();
        if (dwidth == -1 || dheight == -1) return;

        int vwidth = parentWidth;// here,you need to pass the width of parentview
    //  int vwidth = this.getWidth();           
        float scale = (float) vwidth / (float) dwidth;

        final int vheight = (int) (dheight * scale);
        scale(scale, vwidth, vheight);
    }

    private void scale(float scale, int newWidth, int newHeight) {
        final ViewGroup.LayoutParams params = this.getLayoutParams();
        params.width = newWidth;
        params.height = newHeight;
        this.setLayoutParams(params);
        this.setScaleType(ScaleType.MATRIX);
        final Matrix matrix = new Matrix();
        matrix.setScale(scale, scale);
        this.setImageMatrix(matrix);
    }

}

Note:

Don't forget to call fitXUniformly(parentWidth); . here, parentWidth will be the width of CustomImageView 's parent.

I hope it will be helpful !!

链接地址: http://www.djcxy.com/p/58094.html

上一篇: 我如何使用熊猫来计算加权移动平均数

下一篇: ImageView:填充水平维持高宽比