ImageView adjustViewBounds无法正常工作

时间:2011-10-10 22:58:33

标签: android imageview android-imageview

我有一个带有android:layout_width=100dpandroid:layout_height=wrap_contentandroid:adjustViewBounds=true

的ImageView

它的来源是50 x 50像素的图片。但不保留纵横比 - ImageView的高度为50px,而不是100px(即adjustViewBounds不起作用)。如果我有一个200x200px的图片它可以工作 - 宽度和高度是100px。此代码生成100px宽和50px高的图片,但src图像是正方形:

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

    <ImageView
        android:id="@+id/photo"
        android:src="@drawable/icon"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:scaleType="fitXY"
        android:adjustViewBounds="true" />

</LinearLayout>

5 个答案:

答案 0 :(得分:65)

问题在于adjustViewBounds 不会增加ImageView的大小超出drawable的自然维度。它只会缩小视图以保持纵横比;如果您提供500x500图像而不是50x50图像,这应该可以。

如果您对实施此行为的地点感兴趣,请参阅ImageView.java's onMeasure implementation

一种解决方法是实现在ImageView中更改此行为的自定义onMeasure

答案 1 :(得分:11)

有一种更简单的方法。像这样制作你的ImageView:

<ImageView
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:scaleType="fitCenter"
  android:adjustViewBounds="true"/>

这样 drawable将通过保留拉伸以适合ImageView中心 纵横比。我们只需计算合适的高度即可使其成比例 所以我们没有任何空白:

private void setImageBitmap(Bitmap bitmap, ImageView imageView){
    float i = ((float)imageWidth)/((float)bitmap.getWidth());
    float imageHeight = i * (bitmap.getHeight());
    imageView.setLayoutParams(new RelativeLayout.LayoutParams(imageWidth, (int) imageHeight));
    imageView.setImageBitmap(bitmap);
}

答案 2 :(得分:2)

除了@ RomanNurik的answer

您可以找到工作解决方案here,复制粘贴代码或只添加Gradle依赖

dependencies {
    compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.1'
}

P.S。 @Nilzor提供的解决方案对我不起作用

答案 3 :(得分:0)

我有类似的要求;在我的情况下,我希望图像是方形的,并希望ImageView匹配宽高比,这样我就可以使用它的背景和填充来绘制边框。

我在这里阅读了答案,但我没有覆盖ImageView,而是决定制作一个布局,保证其内容(应该只有一个视图)是方形的。这样我就可以在里面使用标准的ImageView。 (你永远不会知道,我可能想在以后制作其他东西。尽管可能不是。)

如果它对其他人有用,请在此处输入代码(随意复制)。可能存在错误,因为我刚刚将其用于我的应用程序然后停止了。 :)

public class SquareLayout extends ViewGroup
{
    public SquareLayout(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

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

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

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {
        // Work out width and height, and square size.
        int width = r - l;
        int height = b - t;

        int size, xOffset, yOffset;
        if(width < height)
        {
            size = width;
            xOffset = 0;
            yOffset = (height - size) / 2;
        }
        else
        {
            size = height;
            xOffset = (width - size) / 2;
            yOffset = 0;
        }

        for(int i = 0; i < getChildCount(); i++)
        {
            View child = getChildAt(i);
            child.layout(xOffset, yOffset, size + xOffset, size + yOffset);
        }
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
        // Get width and height.
        int w = -1, h = -1;
        switch(MeasureSpec.getMode(widthMeasureSpec))
        {
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            w = MeasureSpec.getSize(widthMeasureSpec);
            break;

        case MeasureSpec.UNSPECIFIED:
            break;
        }
        switch(MeasureSpec.getMode(heightMeasureSpec))
        {
        case MeasureSpec.AT_MOST:
        case MeasureSpec.EXACTLY:
            h = MeasureSpec.getSize(heightMeasureSpec);
            break;

        case MeasureSpec.UNSPECIFIED:
            break;
        }

        // If only one of width/height is unspecified, set them both the same.
        if(w == -1 && h != -1)
        {
            w = h;
        }
        else if(h == -1 && w != -1)
        {
            h = w;
        }

        // Either they're both specified or both unspecified.
        int childMeasureSpec;
        if(w == -1)
        {
            childMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }
        else
        {
            childMeasureSpec = MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY);
        }

        // Pass through to children.
        int maxDimension = 1;
        for(int i = 0; i < getChildCount(); i++)
        {
            View child = getChildAt(i);
            child.measure(childMeasureSpec, childMeasureSpec);
            maxDimension = Math.max(maxDimension, child.getMeasuredWidth());
            maxDimension = Math.max(maxDimension, child.getMeasuredHeight());
        }

        if(w == -1)
        {
            w = maxDimension;
            h = maxDimension;
        }

        setMeasuredDimension(w, h);
    }
}

答案 4 :(得分:-1)

此行将为您完成android:scaleType =“ fitXY”