根据填充宽度和比例缩放ImageView Android

3
我有一个ImageView,我将其用作按钮,并希望它按比例缩放到设备的宽度,然后按照比例缩放高度。我一直在遵循这个线程:如何缩放ImageView中的图像以保持纵横比,尝试了所有方法但没有起作用。
以下是我的XML代码:
 <ImageView
        android:id="@+id/th_button"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_above="@+id/towing_button"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:layout_marginTop="50dp"
        android:adjustViewBounds="true"
        android:clickable="true"
        android:fitsSystemWindows="true"
        android:scaleType="fitCenter"
        android:src="@drawable/call_th_button_selector" />

奇怪的是,在Eclipse预览时它可以正常工作,但在我的设备上测试时它不会缩放高度。
有人知道解决办法吗?

android:scaleType="centerCrop" 尝试这个 - Vijju
@jay 谢谢,但我已经尝试过了,它不起作用。 - PaperThick
2个回答

3

我实际上为此创建了一个小部件。你只需要将ImageView放入RatioRelativeLayout中(这个小部件:https://github.com/elimirks/RatioRelativeLayout)。

示例在Github页面上,但我也会在此处粘贴:

<my.package.RatioRelativeLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    heightRatio="0.75"
>
    <View
        android:layout_width="25dp"
        android:layout_height="match_parent"
        android:background="#f00"
    />
</my.package.RatioRelativeLayout>

你也可以使用setMaxHeight来设置它允许的最大高度。在我的应用程序中,我将其用于横向查看照片,以便图像不会比设备的宽度更高。


嗨,我一直希望有更简单的解决方案,但我会尝试这个 :) - PaperThick

3
保持比例对于ImageView来说不适用于图片小于实际视图的情况。我通过扩展ImageView的onMeasure()方法解决了这个问题。
public class ExpandableImageView extends ImageView {

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

    private boolean getAdjustViewBound(){
        return true;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int w;
        int h;

        // Desired aspect ratio of the view's contents (not including padding)
        float desiredAspect = 0.0f;

        // We are allowed to change the view's width
        boolean resizeWidth = false;

        // We are allowed to change the view's height
        boolean resizeHeight = false;

        final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);

        if (getDrawable() == null) {
            w = h = 0;
        } else {
            w = getDrawable().getIntrinsicWidth();
            h = getDrawable().getIntrinsicHeight();
            if (w <= 0) w = 1;
            if (h <= 0) h = 1;

            // We are supposed to adjust view bounds to match the aspect
            // ratio of our drawable. See if that is possible.
            if (getAdjustViewBound()) {
                resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
                resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;

                desiredAspect = (float) w / (float) h;
            }
        }

        int pleft = getPaddingLeft();
        int pright = getPaddingRight();
        int ptop = getPaddingTop();
        int pbottom = getPaddingBottom();

        int widthSize;
        int heightSize;

        if (resizeWidth || resizeHeight) {
            /* If we get here, it means we want to resize to match the
                drawables aspect ratio, and we have the freedom to change at
                least one dimension. 
            */

            // Get the max possible width given our constraints
            widthSize = resolveAdjustedSize(w + pleft + pright, widthMeasureSpec);

            // Get the max possible height given our constraints
            heightSize = (int) (widthSize / desiredAspect);

            if (desiredAspect != 0.0f) {
                // See what our actual aspect ratio is
                float actualAspect = (float)(widthSize - pleft - pright) /
                                        (heightSize - ptop - pbottom);

                if (Math.abs(actualAspect - desiredAspect) > 0.0000001) {

                    boolean done = false;

                    // Try adjusting width to be proportional to height
                    if (resizeWidth) {
                        int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
                                pleft + pright;
                        if (newWidth <= widthSize) {
                            widthSize = newWidth;
                            done = true;
                        } 
                    }

                    // Try adjusting height to be proportional to width
                    if (!done && resizeHeight) {
                        int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
                                ptop + pbottom;
                        if (newHeight <= heightSize) {
                            heightSize = newHeight;
                        }
                    }
                }
            }
        } else {
            /* We are either don't want to preserve the drawables aspect ratio,
               or we are not allowed to change view dimensions. Just measure in
               the normal way.
            */
            w += pleft + pright;
            h += ptop + pbottom;

            w = Math.max(w, getSuggestedMinimumWidth());
            h = Math.max(h, getSuggestedMinimumHeight());

            widthSize = resolveSizeAndState(w, widthMeasureSpec, 0);
            heightSize = resolveSizeAndState(h, heightMeasureSpec, 0);
        }

        setMeasuredDimension(widthSize, heightSize);
    }


    private int resolveAdjustedSize(int desiredSize, int measureSpec) {
        int result = desiredSize;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize =  MeasureSpec.getSize(measureSpec);
        switch (specMode) {
            case MeasureSpec.UNSPECIFIED:
                /* Parent says we can be as big as we want. Just don't be larger
                   than max size imposed on ourselves.
                */
                result = desiredSize;
                break;
            case MeasureSpec.AT_MOST:
                // Parent says we can be as big as we want, up to specSize. 
                // Don't be larger than specSize, and don't be larger than 
                // the max size imposed on ourselves.
                result = Math.min(desiredSize, specSize);
                break;
            case MeasureSpec.EXACTLY:
                // No choice. Do what we are told.
                result = specSize;
                break;
        }
        return result;
    }
}

然后在XML中使用FitXY比例类型:

<com.thepackagename.ExpandableImageView  
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    android:src="@drawable/img"/>

希望这有所帮助!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接