【问题标题】:How to prevent shrinking ImageViews in LinearLayout?如何防止在 LinearLayout 中缩小 ImageView?
【发布时间】:2014-01-10 04:22:43
【问题描述】:

我在一个行为不端的 Android 应用中有一个布局。现在,它看起来像这样:

我们的想法是让 3 张图像及其反射作为单独的图像排列在它们下方。如果我只有图像(只有第一个嵌套的 LinearLayout,如下所示),那么图像显示得很好,它们的原始分辨率和均匀间隔。但是在添加了第二个线性布局(反射)后,显示的图像比应有的要小得多。

图片中的那些反射图像显示的尺寸正确,并且图像本身应该与反射一样宽。如果它们正确显示,则图像顶部到反射底部应该填满屏幕的高度。但他们不是。我已经在图像视图和线性布局(也是不同的 scaleTypes)上尝试了很多 layout_width 和 layout_height 的组合,但没有什么能阻止图像由于某种原因缩小。谁能提出原因?

<?xml version="1.0" encoding="utf-8"?>

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

    <!-- IMAGES -->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="3">

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

    <!-- IMAGE REFLECTIONS -->
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:weightSum="3">

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"" />

        <ImageView 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

    </LinearLayout>

</LinearLayout>

另外,我并没有死心塌地使用 LinearLayouts,因此欢迎提供替代想法。

更新:
这是为每个 ImageView 添加背景颜色后的外观:

...这就是它的实际外观。这是通过将每个海报 ImageView 的 layout_width 和 layout_height 分别设置为 333px 和 500px 来实现的。但我不想这样做。当屏幕上显示的图像少于 3 张时,它会导致海报和反射之间的水平对齐问题:

【问题讨论】:

    标签: android android-layout android-linearlayout android-imageview android-xml


    【解决方案1】:

    如果您的 ImageView 在加载电影海报图像之前显示占位符图像(例如在 android:src 属性中),缩小的可能原因是您的占位符图像与电影海报图像的纵横比不同.

    ImageView 中似乎存在一个错误,有时图像被调整为与占位符图像相同的纵横比。

    尝试将占位符图片调整为与电影海报图片相同的宽高比。

    【讨论】:

      【解决方案2】:

      尝试这样做,我只是给父线性布局添加了权重......

          <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical" >
      
          <!-- IMAGES -->
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:orientation="horizontal"
              android:weightSum="3" >
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
          </LinearLayout>
      
          <!-- IMAGE REFLECTIONS -->
      
          <LinearLayout
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              android:orientation="horizontal"
              android:weightSum="3" >
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
      
              <ImageView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_weight="1" />
          </LinearLayout>
      
      </LinearLayout>
      

      【讨论】:

      • 不幸的是没有运气。它只是将反射推离图像更远,但使图像具有相同的大小和相同的位置。此外,我收到“嵌套权重对性能不利”警告。
      • 你的反射效果如何?尝试在 xml 中设置硬编码图像并检查是否有效。如果是,我怀疑反射代码的创建。
      • 海报图片存储在内存中。通过对海报图像进行转换,在代码中动态生成反射。每个海报图像视图的源使用 setImageDrawable() 设置,每个反射图像视图的源使用 setImageBitmap() 设置。如果我将海报图像的宽度和高度设置为硬编码的像素值 (333 x 500),这是它们的原始分辨率,我实际上可以让它看起来像我想要的那样,但这会导致另一个问题。如果我只有 1 或 2 张图片要展示,则反射不会与海报水平对齐。
      【解决方案3】:

      试试这个,只需将ImageView 的宽度设置为0dp,这样就可以了。并通过此链接LinearLayout to build a row of elements. 它对进一步使用非常有用。

      <!-- IMAGES -->
      <LinearLayout
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:weightSum="3">
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1" />
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1"" />
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1" />
      
      </LinearLayout>
      
      <!-- IMAGE REFLECTIONS -->
      <LinearLayout
          android:orientation="horizontal"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:weightSum="3">
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1" />
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1"" />
      
          <ImageView 
              android:layout_width="0dp"
              android:layout_height="wrap_content"
              android:layout_weight="1" />
      
      </LinearLayout>
      

      【讨论】:

      • 将宽度设置为 0dp 不起作用。我还尝试在根 LinearLayout 和嵌套的 LinearLayouts 上使用baselineAligned,在 ImageViews 上有和没有 0dp。没有骰子。
      • 从您的布局中删除 android:weightSum="3" 属性
      • 仅删除 LinearLayouts 上的 weightSums 没有任何效果,大概是因为每个单独的 imageview 上的 layout_weights 仍然处于活动状态并且执行完全相同的操作。删除 layout_weights 也符合您的预期。除了线性布局中的图像视图不再等间距外,一切都相同,它们被捆绑在一起。
      • weightSum 定义最大重量总和。如果未指定,则通过添加所有子项的 layout_weight 来计算总和。因此,在您的情况下,您的示例中的行为将与省略 weightSum 相同。 documentation
      【解决方案4】:
      • 将所有ImageView的layout_width改为0px,这样:

        原因是,如果 layout_width 不是 0,android 将不会查看 layout_weight(这取决于 android 版本)

      • 除此之外,请确保您的图像足够大(像素方面),如果您不能保证,您可能需要根据需要扩展 ImageView:

        1. 你有一个固定的纵横比(最容易写)

          @Override
          protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
              super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(
                      (int) (MeasureSpec.getSize(widthMeasureSpec) * ASPECT_RATIO),
                      MeasureSpec.EXACTLY));
          }
          
        2. 您希望图像根据源图像的纵横比调整其高度(开始查看here

      • 根据你上面的决定设置一个 scaleType (link)

      【讨论】:

      • 不走运。我尝试将所有图像(海报和倒影)以及海报和倒影都设置为 0px 宽度,但这些更改都没有改变任何东西。
      • 检查我更新的答案,你可能应该选择 centerCrop 或 fitXY 作为你的 scaletype
      • 我已经在 ImageViews 上尝试了各种不同类型的 scaleType。他们都没有工作。图像本身足够大。海报图像实际上与反射图像的宽度相同。如果您要将海报缩放到该宽度,并保持纵横比不变,那么这就是海报图像应该的尺寸
      • 在每个正常图像上设置红色背景色,在每个反射图像上设置蓝色背景色。并添加新的截图
      • BG 颜色完全符合您的期望。两种颜色分别覆盖屏幕的整个宽度和图像的高度。反射图像下方的区域没有颜色。我正在更新帖子。
      【解决方案5】:

      我将此作为第二个答案发布,因为我假设错误在不同的部分: 您的屏幕高度可能不够高以容纳正常图像 + 反射,因此第一行被压扁并缩小图像以匹配纵横比。尝试将其包装在 ScrollView 中,这应该可以解决问题,但可能不是您想要的结果。代码如下:

      请注意,我将包装 LinearLayout 的 layout_height 更改为 wrap_content

      <?xml version="1.0" encoding="utf-8"?>
      
      <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent">
      
          <LinearLayout
                  android:orientation="vertical"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content">
      
              <!-- IMAGES -->
              <LinearLayout
                      android:orientation="horizontal"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:weightSum="3">
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
              </LinearLayout>
      
              <!-- IMAGE REFLECTIONS -->
              <LinearLayout
                      android:orientation="horizontal"
                      android:layout_width="match_parent"
                      android:layout_height="wrap_content"
                      android:weightSum="3">
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
                  <ImageView
                          android:layout_width="0px"
                          android:layout_height="wrap_content"
                          android:layout_weight="1"/>
      
              </LinearLayout>
      
          </LinearLayout>
      </ScrollView>
      

      【讨论】:

        【解决方案6】:

        我找不到方法来完成这项工作,所以我最终只是明确地将海报的宽度和高度设置为其像素值。实际上,我最终还完全采用了一种不同的、更简单的布局,其中一个以 RelativeLayout 作为根,包含六个 ImageView(3 个海报及其反射)。海报收缩效应仍然发生。

        如果有人知道如何解决这个问题,请告诉我。

        【讨论】:

          猜你喜欢
          • 2012-03-06
          • 2019-03-30
          • 1970-01-01
          • 2019-05-07
          • 2018-05-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多