我刚刚阅读了ImageView
的源代码,如果不使用本主题中的子类解决方案,基本上是不可能的。在ImageView.onMeasure
方法中,我们会遇到以下代码:
// Get the max possible width given our constraints
widthSize = resolveAdjustedSize(w + pleft + pright, mMaxWidth, widthMeasureSpec);
// Get the max possible height given our constraints
heightSize = resolveAdjustedSize(h + ptop + pbottom, mMaxHeight, heightMeasureSpec);
在此,h
和w
是图像的尺寸,p*
表示填充。
接下来:
private int resolveAdjustedSize(int desiredSize, int maxSize,
int measureSpec) {
...
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = Math.min(desiredSize, maxSize);
如果您设置了
layout_height="wrap_content"
,它将设置
widthSize = w + pleft + pright
,换句话说,最大宽度等于图像宽度。
这意味着,除非您设置了确切的大小,否则图像永远不会被放大。我认为这是一个错误,但祝你好运,让谷歌注意到并修复它。
编辑:我自己提交了错误报告,他们说已经在未来的版本中修复了!
另一种解决方案
这是另一种子类解决方案,但您在理论上应该(我没有真正测试过!)能够在任何地方使用它
ImageView
。要使用它,请设置
layout_width="match_parent"
和
layout_height="wrap_content"
。它比接受的解决方案更通用。例如,您可以根据高度适应或根据宽度适应。
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
public class StretchyImageView extends ImageView
{
public StretchyImageView(Context context)
{
super(context);
}
public StretchyImageView(Context context, AttributeSet attrs)
{
super(context, attrs);
}
public StretchyImageView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getDrawable() == null)
return;
final int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
int w = getDrawable().getIntrinsicWidth();
int h = getDrawable().getIntrinsicHeight();
if (w <= 0)
w = 1;
if (h <= 0)
h = 1;
float desiredAspect = (float) w / (float) h;
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
int pleft = getPaddingLeft();
int pright = getPaddingRight();
int ptop = getPaddingTop();
int pbottom = getPaddingBottom();
int widthSize = getMeasuredWidth();
int heightSize = getMeasuredHeight();
if (resizeWidth && !resizeHeight)
{
int newWidth = (int) (desiredAspect * (heightSize - ptop - pbottom)) + pleft + pright;
setMeasuredDimension(newWidth, heightSize);
}
else if (resizeHeight && !resizeWidth)
{
int newHeight = (int) ((widthSize - pleft - pright) / desiredAspect) + ptop + pbottom;
setMeasuredDimension(widthSize, newHeight);
}
}
}