我刚才读了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:
/* Parent says we can be as big as we want. Just don't be larger
than max size imposed on ourselves.
*/
result = Math.min(desiredSize, maxSize);
所以,如果你有一个layout_height="wrap_content"
它将设置widthSize = w + pleft + pright
,或者换句话说,最大宽度等于图像宽度。
这意味着,,除非你设置一个确切的大小,图像从来没有放大。我认为这是一个错误,但让Google注意或修复它会带来好运。 编辑:吃我自己的话,我提交了a bug report,他们说它已经在未来的版本中修复!
另一种解决方案
这里是另一个子类解决办法,但你应该(理论上,我还没有真正测试过了!),可以在任何地方你ImageView
使用它。要使用它,请设置layout_width="match_parent"
和layout_height="wrap_content"
。它比公认的解决方案还要普遍得多。例如。你可以做到适合身高和适合身高。
import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;
// This works around the issue described here: http://stackoverflow.com/a/12675430/265521
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)
{
// Call super() so that resolveUri() is called.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// If there's no drawable we can just use the result from super.
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;
// Desired aspect ratio of the view's contents (not including padding)
float desiredAspect = (float) w/(float) h;
// We are allowed to change the view's width
boolean resizeWidth = widthSpecMode != MeasureSpec.EXACTLY;
// We are allowed to change the view's height
boolean resizeHeight = heightSpecMode != MeasureSpec.EXACTLY;
int pleft = getPaddingLeft();
int pright = getPaddingRight();
int ptop = getPaddingTop();
int pbottom = getPaddingBottom();
// Get the sizes that ImageView decided on.
int widthSize = getMeasuredWidth();
int heightSize = getMeasuredHeight();
if (resizeWidth && !resizeHeight)
{
// Resize the width to the height, maintaining aspect ratio.
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);
}
}
}
做所有的Android装置具有完全相同的宽度/高度比γ如果不是,那么根本不可能在保持原始比例的情况下缩放图像以适应整个宽度/高度... – NoozNooz42 2010-06-07 16:09:29
不,我不希望图像填满屏幕,只是为了缩放到屏幕宽度,只要图像的比例正确,不关心图像垂直占用多少屏幕。 – fredley 2010-06-07 16:10:41
类似的问题,很好的答案:http://stackoverflow.com/questions/4677269/how-to-stretch-three-images-across-the-screen-preserving-aspect-ratio – 2011-12-27 20:10:59