ImageView的高度如何设置为显示图片的wrap_content?

40

我希望 ImageView 的宽度由其父容器设置,并且高度应该是等比例的。这样做的原因是接下来要显示一个 TextView,我希望它能准确地位于 ImageView 的下方。

我可以使用以下代码正确显示图像:

android:layout_width="fill_parent"
android:layout_height="fill_parent"

但是ImageView的高度变成了父级高度,远远大于所显示的拉伸图像的大小。一个想法是使父级在垂直方向上更小,但是...我还不知道拉伸图像的大小。

以下方法无法解决问题,因为小图像在水平方向上无法填充满。

android:layout_width="fill_parent"
android:layout_height="wrap_content"

把东西搞乱了

android:layout_height="wrap_content"

尝试使用包围它的RelativeLayout、FrameLayout和LinearLayout都没有帮助。

有什么想法吗?


你尝试过类似这个的吗?http://developer.android.com/reference/android/widget/ImageView.ScaleType.html - fgeorgiew
如果您想要保持纵横比,您需要在线性布局中使用权重。 - Jitender Dev
1
@fgeorgiew 是的,我尝试了所有这些。很遗憾,没有运气。 - Scott Johansen
@Brontok 我试过了,但是TextView的大小变得很奇怪。 - Scott Johansen
4个回答

99
你需要将adjustViewBounds设置为true。
imageView.setAdjustViewBounds(true);

1
你可以从界面上完成这个操作。完美运作。 - Silviu St
11
在XML中,您需要添加android:adjustViewBounds="true"。请参见其他答案->https://dev59.com/FmIk5IYBdhLWcg3wBaD7#19673468@kit谢谢 - CrandellWS

40

如果您的实际图像大小等于或大于ImageView的宽度和高度,则可以使用adjustViewBounds属性;如果实际图像大小小于ImageView的宽度和高度,则可以根据要求使用scaleType属性在ImageView中显示图像。

1. 实际图像大小等于或大于所需的ImageView宽度和高度。

<ImageView
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:src="@drawable/ic_launcher"/>

2. 实际图像大小小于 ImageView 所需宽度和高度。

<ImageView
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    android:src="@drawable/ic_launcher"/>

如果我改用FrameLayout,问题就解决了。但RelativeLayout或LinearLayout不行。不过,如果我只是设法将TextView附加在ImageView正下方,这样就可以了。(android:layout_below不起作用)- 非常感谢! - Scott Johansen
如果我将图像和文本放入新的RelativeLayout中,它会被对齐,但是图像不再位于中心,整个内容都在中心。 - Scott Johansen
我的目标是将一张图片1作为背景,居中显示。然后在其上方居中显示较小的图片2,并在图片2正下方放置文本。使用ViewFlipper进行动画等操作来更改图片2和文本。 - Scott Johansen

8

我曾多次遇到相同的问题,并在查阅现有的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" />

0

这是我能让它工作的唯一方法,将第二个ImageView放在中心位置,并且比第一个ImageView小,TextView放在第二个ImageView下面。

不幸的是,第二个ImageView使用了固定的“200dp”图像大小,因此在不同尺寸的设备上看起来不同。

它还破坏了我的ViewFlipper,因为我尝试在第二个ImageView和TextView周围使用任何布局都会使它们移动或调整大小。

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >
    <ImageView
        android:id="@+id/imageview1"
        android:contentDescription="@string/desc"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/background" />
    <ImageView
        android:id="@+id/imageview2"
        android:layout_centerInParent="true"
        android:contentDescription="@string/desc"
        android:layout_height="200dp"
        android:layout_width="200dp" 
        android:adjustViewBounds="true"
        android:src="@drawable/image2" />
    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_below="@id/imageview2"
        android:paddingLeft="8dp"
        android:paddingRight="8dp"
        android:gravity="center"
        android:textSize="26sp"
        android:textColor="#333"
        android:background="#fff"
        android:text="this is the text under the image right here"
        />
</RelativeLayout>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接