我曾多次遇到相同的问题,并在查阅现有的StackOverflow答案后意识到,没有一个答案能够完美地解释这个问题的解决方法。所以在这里提供:
API 17+
imageView.setAdjustViewBounds(true);
或者(在XML中)
android:adjustViewBounds="true"
可以解决这个问题,在布局中无论图像资源的实际大小如何,它都会将您的图像缩放到所需的尺寸。
低于API 17
低于API 17 android:adjustViewBounds="true"
仅适用于缩小图像,而不能放大图像,即如果图像源的实际高度小于您在布局中要实现的尺寸,则wrap_content
将使用较小的高度而不是按照您的期望缩放'up'(放大)图像。
因此,在API 17及以下版本中,您别无选择,只能使用自定义ImageView来实现此行为。您可以编写自定义ImageView,也可以使用已经完成了该工作的库。
使用库
可能有多个可以解决此问题的库之一是:
compile 'com.inthecheesefactory.thecheeselibrary:adjustable-imageview:1.0.0'
使用方法如下:
<com.inthecheesefactory.thecheeselibrary.widget.AdjustableImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/your_drawable"/>
使用自定义视图
除了使用现有的库之外,您还可以自己编写自定义视图,例如:
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ImageView;
public class ScalableImageView extends ImageView {
boolean adjustViewBounds;
public ScalableImageView(Context context) {
super(context);
}
public ScalableImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScalableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
this.adjustViewBounds = adjustViewBounds;
super.setAdjustViewBounds(adjustViewBounds);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Drawable drawable = getDrawable();
if (drawable == null) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
return;
}
if (adjustViewBounds) {
int drawableWidth = drawable.getIntrinsicWidth();
int drawableHeight = drawable.getIntrinsicHeight();
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
if (heightMode == MeasureSpec.EXACTLY && widthMode != MeasureSpec.EXACTLY) {
int height = heightSize;
int width = height * drawableWidth / drawableHeight;
if (isInScrollingContainer())
setMeasuredDimension(width, height);
else
setMeasuredDimension(Math.min(width, widthSize), Math.min(height, heightSize));
} else if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
int width = widthSize;
int height = width * drawableHeight / drawableWidth;
if (isInScrollingContainer())
setMeasuredDimension(width, height);
else
setMeasuredDimension(Math.min(width, widthSize), Math.min(height, heightSize));
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
private boolean isInScrollingContainer() {
ViewParent parent = getParent();
while (parent != null && parent instanceof ViewGroup) {
if (((ViewGroup) parent).shouldDelayChildPressedState()) {
return true;
}
parent = parent.getParent();
}
return false;
}
}
...你可以按照以下方式(XML)使用:
<com.YOUR_PACKE_NAME.ScalableImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="@drawable/your_drawable" />