ImageView 调整视图边界不起作用
Posted
技术标签:
【中文标题】ImageView 调整视图边界不起作用【英文标题】:ImageView adjustViewBounds not working 【发布时间】:2011-12-04 21:34:15 【问题描述】:我有一个带有 android:layout_width=100dp
、android:layout_height=wrap_content
和 android: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 调整视图边界不起作用的主要内容,如果未能解决你的问题,请参考以下文章