29

这是一个简单的布局:

      <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <ImageView
                android:id="@+id/companyIcon"
                android:layout_width="wrap_content"
                android:layout_height="40dp" <!-- notice I've limited a height -->
                android:scaleType="fitStart"
                android:adjustViewBounds="true"
                android:layout_alignParentLeft="true" />

            <TextView
                android:id="@+id/companyName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/companyIcon"
                android:layout_marginLeft="3dp"
                android:layout_centerVertical="true"
                android:textStyle="bold"
                android:textColor="#20526d" />
        </RelativeLayout>

我将设置的图像高度setImageBitmap()超过 40dp。ImageView使用这种布局,我在and之间有一个额外的空间TextView,它是从哪里来的? 在此处输入图像描述

但是在我用 with 包裹之后ImageViewFrameLayout我没有这个不必要的额外空间:

<RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <FrameLayout
                android:id="@+id/image_container"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/companyIcon"
                    android:layout_width="wrap_content"
                    android:layout_height="40dp"
                    android:scaleType="fitStart"
                    android:adjustViewBounds="true"
                    android:layout_alignParentLeft="true" />
            </FrameLayout>

            <TextView
                android:id="@+id/companyName"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_toRightOf="@id/image_container"
                android:layout_marginLeft="3dp"
                android:layout_centerVertical="true"
                android:textStyle="bold"
                android:textColor="#20526d" />
        </RelativeLayout>

结果:

在此处输入图像描述

你们能解释一下为什么我要按ImageView预期FrameLayout去做吗?非常感谢你。

4

6 回答 6

30

我将通过 setImageBitmap() 设置的图像高度超过 40dp。使用这个布局我在 ImageView 和 TextView 之间有一个额外的空间,它是从哪里来的?

由于android:layout_height="40dp"带有 a android:scaleType="fitStart",图像被缩小(并且向左/开始)以适应高度,所以这个“额外空间”实际上是图像的原始宽度,因为你的android:layout_width="wrap_content". 我用我自己的大于40dp. 当您选择 时ImageView,您可以看到它的边界拉伸到图像的原始宽度。

原始布局

为了进一步证明这一点,如果我设置android:scaleType="center",则不应用任何拟合,您可以看到ImageView的原始宽度。

原始布局未缩放以适应

你们能解释一下为什么我要将 ImageView 放入 FrameLayout 以达到预期的效果吗?

看来,自从您FrameLayout使用以来android:layout_width="wrap_content"ImageView由于android:adjustViewBounds="true". 奇怪的是,它ImageView本身使用android:layout_width="wrap_content",但显示的是原始图像的宽度,而不是缩放后的宽度。我的预感是在应用缩放之前ImageView设置了 s的高度和宽度,因此获取原始图像的宽度,但是在应用缩放之后父获取其子图像的缩放宽度。这可能不是真的,但对我来说似乎是这样。ImageViewFrameLayoutImageView

但是,您可以FrameLayout通过android:maxHeight="40dp"ImageView. 然后,您可以进行设置android:layout_height="wrap_content",以便您的图像可以比40dp图像更小。

<ImageView
    android:id="@+id/companyIcon"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:adjustViewBounds="true"
    android:maxHeight="40dp"
    android:scaleType="fitStart" />

使用 maxHeight 的原始布局

于 2013-02-14T01:08:58.697 回答
4

这几乎适用于所有观点,但答案是专门考虑到​​的ImageView

设置高度和宽度的指南

仅选择这三个选项之一。

  1. 将高度和宽度WRAP_CONTENT设置为“ ”
  2. 将高度和宽度FILL_PARENT设置为“ ”
  3. 将高度和宽度FIXED SIZE设置为“ ”

    *避免混合使用它们说Width=WRAP_CONTENT and Height=FILL_PARENT

为 ImageView 设置 SCALETYPE 的指南

ScaleType 是做什么的?

它将您设置为 ImageView 的图像缩放,它不会缩放 ImageView,因此当您将其设置为 fitStart 时,它将缩放您的图像并显示在右侧,但您的 imageView 在高度和宽度方面将与您指定的相同.

就像您使用WRAP_CONTENT高度和宽度一样,您不需要指定ScaleType 因为您的 ImageView 会自动与您的图像一样大。

就像您使用FILL_PARENT高度和宽度一样,您可以选择在中心、开始、结束或全视图中显示图像。因此,您可以根据此选择您的 ScaleType。

就好像您使用FIXED_SIZEfpr 高度和宽度一样,您应该选择scaletype=FITXY.


将 Image 设置为 ImageView 的指南

就像您在 XML 中静态设置图像一样,您手上只有一张图像,因此您可以根据布局设计创建所需大小的图像,然后继续使用 WRAP_CONTENT

就好像您在从某个地方下载图像后在运行时设置图像一样,那时下载图像并创建您喜欢的大小的位图,然后将其设置为 ImageView


具体到您的情况

您可以看到您的图像被拉伸得很长,并且文本不可读,这是因为您已经下载并设置了图像,但高度和宽度更小..而不是您应该这样做,

WRAP_CONTENT在 XML 文件中设置 ImageView 的高度和宽度

                    <ImageView
                    android:id="@+id/companyIcon"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentLeft="true" />

下载所需尺寸的图像,例如 50X100,例如查看此代码

class LoadPics extends AsyncTask<Void, Bitmap, Bitmap> {
    String urlStr;
    ImageView iv;
    int width, height;

    public LoadPics(ImageView iv, String url, int width, int height) {
        this.iv = iv;
        this.urlStr = url;
        this.width = width;
        this.height = height;
    }

    @Override
    protected Bitmap doInBackground(Void... params) {
        try {
                InputStream in = null;
                try {
                    URL url = new URL(urlStr);
                    URLConnection urlConn = url.openConnection();
                    HttpURLConnection httpConn = (HttpURLConnection) urlConn;
                    httpConn.connect();
                    in = httpConn.getInputStream();
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;

                int scale = 2;
                if (o.outHeight > width || o.outWidth > height) {
                    scale = 2 ^ (int) Math.ceil(Math.log(width
                            / (double) Math.max(o.outHeight, o.outWidth))
                            / Math.log(0.5));
                }

                if (scale <= 1 && o.outHeight > 150) {
                    scale = 5;
                }

                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize = scale;
                Bitmap b1 = BitmapFactory.decodeStream(in, null, o2);
                b1 = Bitmap.createScaledBitmap(b1, width, height, true);
                loader.addToCache(urlStr, b1);
                publishProgress(b1);

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onProgressUpdate(Bitmap... values) {
        super.onProgressUpdate(values);
        iv.setImageBitmap(values[0]);
    }
}

并用你的参数调用这个方法,

new LoadPics(ivUser,imgURL,100,50).execute();
于 2013-02-14T06:55:25.957 回答
1

尝试android:scaleType="fitStart"用这个替换android:scaleType="fitXY"


编辑

在您的图像视图中,您应该将 imagView 的宽度设置为wrap-content这将采用图像的大小。如果您对imageView's宽度进行硬编码(就像您通过将宽度指定为 40dp 来完成的那样),那么这在其他 android 移动设备中看起来不会那么好。

尽管如此,如果您想这样做,请尝试加载分辨率较低的图像。如果此图像是200X100分辨率,则尝试将图像加载到100X50您的ImageView

于 2013-01-30T17:31:58.840 回答
0

如果您这样做android:scaleType="FIT_END",但没有FrameLayout,是否会将 Subway 图像放在“Subway”文本附近?我想知道,因为你android:layout_alignParentLeft="true"在那里。我在想,ImageView缩放之前的原始尺寸是没有FrameLayout.

它可能并不重要,但它确实需要一些处理来缩放和调整图像的大小以达到您想要的效果。如果它对您想要做的事情是可行的,我会自己调整图像大小而不是依赖 XML。如果我想迎合多种尺寸,我会制作几种不同的布局。对于您的目的,这当然可能是矫枉过正,我不知道。

于 2013-01-30T22:16:42.933 回答
0

第一个图像中有额外的空间,因为您在图像容器布局中设置了匹配父级。但第二次你在 FrameLayout 中使用了包装内容,这是图像容器。

我建议做这些事情创建线性布局内部相对布局并应用 layout_weight 属性,因此两个视图中的比率将相同。

于 2013-02-12T06:03:43.380 回答
0

尝试将比例类型设置为 center_inside。

于 2013-02-14T02:46:55.250 回答