为什么我需要将ImageView包装到FrameLayout中?

时间:2013-01-30 16:40:44

标签: android android-layout

这是一个简单的布局:

      <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。 使用此布局我在ImageViewTextView之间有一个额外的空格,它来自哪里? enter image description here

但在我用ImageView包裹FrameLayout后,我没有这个不必要的额外空间:

<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>

结果:

enter image description here

你们能否解释一下为什么我要ImageView进入FrameLayout按照预期进行操作?非常感谢你。

6 个答案:

答案 0 :(得分:30)

  

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

由于android:layout_height="40dp"带有android:scaleType="fitStart",因此图像会缩小(并向左/开始)以适合高度,因此这个“额外空间”实际上是原始宽度图片,因为您的android:layout_width="wrap_content"。我使用比40dp更大的自己的图像重新创建了布局。当您选择ImageView时,您可以看到其边界延伸到图像的原始宽度。

Original Layout

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

Original Layout not scaled to fit

  

你们能解释一下为什么我要将ImageView放入FrameLayout以便按照预期进行操作?

由于FrameLayout使用了android:layout_width="wrap_content",因此ImageViewandroid:adjustViewBounds="true"缩放后,ImageView会缩小宽度。奇怪的是,android:layout_width="wrap_content"本身使用ImageView,但显示原始图像的宽度,而不是缩放的宽度。我的预感ImageView s的高度和宽度在应用缩放之前设置为,因此FrameLayout获取原始图像的宽度,但是,在应用缩放之后,父ImageView获得了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" />

{{1}}

Original Layout using maxHeight

答案 1 :(得分:4)

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

设置高度和宽度的指南

仅选择这三个选项中的一个。

  1. 两者的高度和宽度设置为“WRAP_CONTENT
  2. 设置两者高度和 宽度为“FILL_PARENT
  3. 两者的高度和宽度设置为“FIXED SIZE

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

  4. 为ImageView设置SCALETYPE的指南

    ScaleType做什么?

      

    它将您设置的图像缩放到ImageView,它不会缩放   ImageView因此,当您将其设置为fitStart时,它将缩放您的图像和   显示在右侧,但您的imageView将保持相同   高度和宽度,如您所指定的那样。

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

    如果您使用FILL_PARENT作为高度和宽度,您可以选择在中心,开始,结束或完整视图中显示图像..所以基于您可以选择 >您的ScaleType。

    如果您使用FIXED_SIZE fpr的高度和宽度,应选择 scaletype=FITXY


    将图像设置为ImageView的指南

    如果您在XML中设置图像静态,那么您手上有一个图像,因此您可以根据布局设计创建所需尺寸的图像,然后继续WRAP_CONTENT

    从某处下载后,好像是在运行时设置图像,那时下载图像并创建您喜欢的大小的位图,然后将其设置为ImageView


    特定于您的案例

    你可以看到你的图像非常拉伸,而且文字是不可读的,因为你已经下载并设置了图像,但是它的高度和宽度都较小..相反,你应该这样做,

    将XMLView文件中的ImageView高度和宽度设置为WRAP_CONTENT

                        <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();
    

答案 2 :(得分:1)

尝试使用此android:scaleType="fitStart"

替换android:scaleType="fitXY"

修改

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

如果您想这样做,请尝试加载分辨率较低的图像。如果此图片的分辨率为200X100,请尝试在100X50

中加载ImageView的图片

答案 3 :(得分:0)

如果您执行android:scaleType="FIT_END",而没有FrameLayout,是否会将地铁图片放在“地铁”文字附近?我想知道,因为那里有android:layout_alignParentLeft="true"。我认为在缩放之前ImageView的原始大小是没有FrameLayout的布局。

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

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