ImageView 调整视图边界不起作用

Posted

技术标签:

【中文标题】ImageView 调整视图边界不起作用【英文标题】:ImageView adjustViewBounds not working 【发布时间】:2011-12-04 21:34:15 【问题描述】:

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

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

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

    <ImageView
        android:id="@+id/photo"
        android:src="@drawable/icon"
        android:layout_
        android:layout_
        android:scaleType="fitXY"
        android:adjustViewBounds="true" />

</LinearLayout>

【问题讨论】:

正常工作;你能提供一个确切的代码sn-p吗?另外 ImageView 的父级是什么?也许它的父级正在强制某个大小,不允许 ImageView 调整大小。 啊,我找到了问题,现在将提供答案。 【参考方案1】:

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

如果您对实现此行为的位置感兴趣,请参阅ImageView.java's onMeasure implementation。

一种解决方法是实现一个自定义ImageView,以更改onMeasure 中的这种行为。

【讨论】:

你知道有什么库可以修复 imageView 的这种行为吗? 我现在创建了一个 ImageView 版本,如果你有 match_parent/fill_parent,它也可以放大缩小,而原始 ImageView 没有。实际上,我发现这个版本的 ImageView 在动态布局中进行纵横比缩放时更加实用。随意复制。来源:gist.github.com/Nilzor/5402789 一个 ScalingImageView 就像 adjustViewBounds=true 一样工作,并且总是根据宽度和可绘制的内在纵横比改变高度:github.com/triposo/barone/blob/master/src/com/triposo/barone/… 这种行为似乎在 Android 4.3 中有所改变。我的观点现在已经超出了它们的自然大小。你能确认@RomanNurik 吗? @aleb 谢谢工作正常! devisnik - 使用 4.4.2 和 Galaxy Nexus 4.3 不会增加我的 S5 上的图像大小。也许它是特定于设备的。【参考方案2】:

还有一个更简单的方法。让你的 ImageView 像这样:

<ImageView
  android:layout_
  android:layout_
  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);

【讨论】:

这只是一个很好的解决方案,如果在视图中心对齐图像是你想要的。如果您需要灵活对齐,请参阅 Roman Nuriks 的回答和我的评论。【参考方案3】:

除了@RomanNurik 的answer

您可以找到有效的解决方案 here,复制粘贴代码或添加 Gradle 依赖项

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

附: @Nilzor 提供的解决方案对我不起作用

【讨论】:

对于下一个读者,该视图称为com.inthecheesefactory.thecheeselibrary.widget.AdjustableImageView【参考方案4】:

我也有类似的要求;在我的例子中,我希望图像是正方形的,并且希望 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);
    

【讨论】:

【参考方案5】:

这条线会帮你做 android:scaleType="fitXY"

【讨论】:

以上是关于ImageView 调整视图边界不起作用的主要内容,如果未能解决你的问题,请参考以下文章

imageview的marginRight属性不起作用

将快餐栏中的 ImageView 宽度与 Android 中的自定义视图匹配父项不起作用

自我调整大小的表格视图单元格不起作用

在 UIScrollView 中调整内容视图的大小不起作用

Swift - 设置 CALayer 边界或框架不起作用

复合视图的 addSubview 不起作用