ImageView填充父级容器的宽度或高度,但保持长宽比。

49

我有一张正方形的图片(尽管这个问题也适用于矩形图片)。我希望将图片显示得尽可能大,如果需要的话可以拉伸图片以填满其父视图,同时仍然保持纵横比。但是问题在于,我无法拉伸图片并“匹配”ImageView的高度和宽度。

这是我的XML布局文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:padding="10dp">

    <ImageView android:id="@+id/image"
               android:layout_width="fill_parent"
               android:layout_height="fill_parent"
               android:adjustViewBounds="true"
               android:scaleType="fitCenter"
               android:layout_marginTop="10dp"/>

    <TextView android:id="@+id/name"
              android:layout_below="@id/image"
              android:layout_alignLeft="@id/image"
              android:layout_marginTop="20dp"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textSize="18dp"/>

    <TextView android:id="@+id/name2"
              android:layout_below="@id/name"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:textSize="14dp"/>


</RelativeLayout>
我已经尝试了很多组合,使用fill_parentwrap_content和多个scaleType:fitCenterfitStartfitEndcenterInside。它们都以正确的纵横比绘制图像,但没有一种实际上将图像和ImageView本身缩放,导致TextView被推到屏幕下方,ImageView内有空白区域、图像未缩放或图像被裁剪。

我无法找出正确的组合方式。


尝试使用此处给出的答案:https://dev59.com/Bm435IYBdhLWcg3wigux - FoamyGuy
1
@Tim:我已经设置了 adjustViewBounds=true。但它似乎没有调整 ImageView 的边界大小。 - garbagecollector
你尝试过使用 android:scaleType="fitXY" 吗?它会将图像拉伸以匹配您分配的宽度和高度(即,它不会考虑纵横比)。 - Sufian
可能是重复的问题:ImageView adjustViewBounds not working - aleb
你可以尝试该响应:https://dev59.com/1G035IYBdhLWcg3wNtNw#12283909 - OriolJ
显示剩余2条评论
7个回答

115

这些:

android:layout_height="wrap_content"
android:scaleType="fitStart"
android:adjustViewBounds="true"

应该调整图片大小并更改边界的大小以适应新的图像大小。如果在您的设备上没有这样做,请发布您正在使用的图像以及正在测试的设备。


3
无法工作。我无法发布这些图片,因为它们是专有的,但它们只是标准的 128x128 PNG 图片。这也会在模拟器上发生。因此,这不是设备特定的问题。这些图片比 ImageView 更小。我认为问题就出在这里。 - garbagecollector
adjustViewBounds不够,它“不会将ImageView的大小增加到可绘制对象的自然尺寸之外”:https://dev59.com/_2sz5IYBdhLWcg3wsaAN#7732684 - aleb
我认为解决方案是使用scaleType="centerCrop",如果您可以接受图像被裁剪的话... - Christophe Fondacci
@Foam Guy,如果我从服务器获取图像,这个能用吗? - Erum
@Erum 图像来源不应该有关系。 - FoamyGuy
显示剩余3条评论

49
使用以下代码:android:scaleType="fitXY"
有关图像缩放的更多详细信息,请参见此处所述的文章。
总结:
  • center

将图像置于视图中心,但不执行任何缩放

输入图像描述

  • centerCrop

等比例缩放图像(保持图像的宽高比),使得图像的宽度和高度都等于或大于视图的相应尺寸(减去padding)。然后将图像居中显示在视图中

输入图像描述

  • centerInside

等比例缩放图像(保持图像的宽高比),使得图像的宽度和高度都等于或小于视图的相应尺寸(减去padding)

输入图像描述

  • fitCenter

输入图像描述

  • fitEnd

输入图像描述

  • fitStart

输入图像描述

  • fitXY

输入图像描述

  • 矩阵

在绘制时使用图像矩阵进行缩放

输入图像描述

更多细节请参见此处新文章。


1
为什么这个答案没有任何投票?只有这一个对我有效! - Nari Kim Shin
10
因为它没有保持源图像的纵横比。请参见此处 - Stephen Niedzielski
将每个图像显示所有情况对我非常有帮助。谢谢! - Matt
如果 ImageView.background=#000000,你会看到 ImageView 占据了父布局的空间; - Marcos Vasconcelos
最佳答案,现在我能理解它们所有的内容。 - Shady Mohamed Sherif

22

这段 XML 代码将起作用!如果您指定应用程序的宽度始终与窗口相同,则 android:adjustViewBounds="true" 将根据图像的比例设置高度。

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

愿stackoverflow之神保佑你的灵魂。 我花了整整一天的时间,要么是一个狭窄的图像,要么是有白色边框的图像,最后放弃了。今天早上回来后我想到,“嘿,让我谷歌一下”。@garbagecollector 真的应该接受这个答案!! - Иво Недев
@ИвоНедев stackoverflow神明不知为何不保佑我,它没有起作用。图像长宽比未能保持。 - flankechen

13

将此代码与视图布局参数一起使用,参数设置为wrapcontent。

android:adjustViewBounds="true"

希望这样做会起作用。


adjustViewBounds不够用,它“不会将ImageView的大小增加到可绘制对象的自然尺寸之外”:https://dev59.com/_2sz5IYBdhLWcg3wsaAN#7732684 - aleb

4

我有同样的问题,android:adjustViewBounds 没有起到作用,图片顶部有一个填充。在一个相对布局中,宽度和高度都设置为 match_parent:

   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical" android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:background="@color/transparent">

   <ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:scaleType="fitStart"
    android:adjustViewBounds="true" ...

我将相对布局改为线性布局,并使用wrap_content值设置宽度和高度,现在一切正常:

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"

1
经过多个小时的搜索,我还将RelativeLayout更改为LinearLayout。但在我的情况下,ImageView没有显示出来。 - CoolMind
我的ImageView: "<ImageView android:id="@+id/IV_InformationPic" android:layout_width="wrap_content" android:layout_height="300dp" android:adjustViewBounds="true"/>"如果放在RelativeLayout中,ImageView会正确处理其高度,但不知何故左右会有额外的填充。阅读了这个答案和@CoolMind的评论后,我尝试将其更改为LinearLayout,咦,ImageView就没有了侧边填充。我很想理解这个巫术。 - Matan Koby
@MatanKoby,愉快编程!Android有许多秘密和难关。 - CoolMind

3

您尝试过以编程方式进行调整吗?如果您计算您的TextView的高度并根据此调整图像的高度和宽度,我认为这样效果非常好。

private void adjustImageView()
{
    //Get the display dimensions
    DisplayMetrics metrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(metrics);

    //TextView name
    TextView name = (TextView) findViewById(R.id.name);
    name.setText("your name text goes here");
    name.measure(0, 0);

    //name TextView height
    int nameH = name.getMeasuredHeight();

    //TextView name2
    TextView name2 = (TextView) findViewById(R.id.name2);
    name2.setText("your name2 text goes here");
    name2.measure(0, 0);

    //name2 TextView height
    int name2H = name2.getMeasuredHeight();

    //Original image
    Bitmap imageOriginal = BitmapFactory.decodeResource(getResources(), R.drawable.image);

    //Width/Height ratio of your image
    float imageOriginalWidthHeightRatio = (float) imageOriginal.getWidth() / (float) imageOriginal.getHeight();

    //Calculate the new width and height of the image to display 
    int imageToShowHeight = metrics.heightPixels - nameH - name2H;
    int imageToShowWidth = (int) (imageOriginalWidthHeightRatio * imageToShowHeight);

    //Adjust the image width and height if bigger than screen
    if(imageToShowWidth > metrics.widthPixels)
    {
        imageToShowWidth = metrics.widthPixels;
        imageToShowHeight = (int) (imageToShowWidth / imageOriginalWidthHeightRatio);
    }

    //Create the new image to be shown using the new dimensions 
    Bitmap imageToShow = Bitmap.createScaledBitmap(imageOriginal, imageToShowWidth, imageToShowHeight, true);

    //Show the image in the ImageView
    ImageView image = (ImageView) findViewById(R.id.image);
    image.setImageBitmap(imageToShow);
}

0
在ImageView中设置android:layout_height="wrap_content"。 要创建一个宽度等于屏幕宽度,高度按比例设置的图像,请执行以下操作。这里我提到了如何从URL加载图像到ImageView。
Glide.with(context).load(url).asBitmap().into(new SimpleTarget<Bitmap>() {
                    @Override
                    public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) {

                        // creating the image that maintain aspect ratio with width of image is set to screenwidth.
                        int width = imageView.getMeasuredWidth();
                        int diw = resource.getWidth();
                        if (diw > 0) {
                            int height = 0;
                            height = width * resource.getHeight() / diw;
                            resource = Bitmap.createScaledBitmap(resource, width, height, false);
                        }
                                              imageView.setImageBitmap(resource);
                    }
                });

希望这能有所帮助。

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