【问题标题】:Resize parent to match its child调整父级以匹配其子级
【发布时间】:2014-07-30 15:09:03
【问题描述】:

我有一个复杂的 xml 布局,其中一部分是:

...

<FrameLayout
        android:id="@+id/parent"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginLeft="30dp"
        android:layout_marginRight="30dp"
        android:layout_weight="1" >

        <ImageView
            android:id="@+id/flexible_imageview"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:adjustViewBounds="true" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            android:background="@drawable/gradient"
            android:orientation="vertical"
            android:paddingBottom="16dp"
            android:paddingLeft="16dp"
            android:paddingTop="8dp" >

            <TextView
                android:id="@+id/textView1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </LinearLayout>
</FrameLayout>

...

FrameLayout @+id/parent 的高度必须在运行时确定,因为它显示在许多其他视图之上,并且它们必须显示在布局中。这样,FrameLayout 可以完美地填充剩余空间(使用 height="0dp" 和 weight="1" 属性)。

ImageView @+id/flexible_imageview 从网络接收图像,并且始终以正确的纵横比显示。这部分也已经ok了。这个View是最大的,应该决定FrameLayout @+id/parent的大小。

问题是当图像被绘制时,FrameLayout @+id/parent 的宽度没有被调整为换行,而是应该是ImageView @+id/flexible_imageview

感谢任何帮助。

-- 更新--

我已经更新了布局,以澄清一些缺失的部分,并添加所有这些部分背后的原因。

我想要的是有一个尺寸未知的图像 (ImageView @+id/flexible_imageview),在它上面有一个渐变和一些文本。我无法将FrameLayout @+id/parent 尺寸设置为wrap_content,因为必须显示此图像之后的更多视图。如果布局中没有足够的空间,图像 (ImageView @+id/flexible_imageview) 会缩小,直到它完全适合布局,但它应该保持其纵横比,以及其顶部的渐变/文本。

@drawable/gradient 只是:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <gradient
        android:angle="270"
        android:endColor="#aa000000"
        android:startColor="#00000000" />
</shape>

-- 更新 2--

我在下面添加了两张图片来演示正在发生的事情以及应该发生的事情:

错误:

正确:

【问题讨论】:

  • adjustViewBounds 不会影响图像视图的 match_parent 尺寸。当您手动降低高度时,使用默认 scaleType (FIT_CENTER) 绘制时图像正在调整大小,但视图仍然是相同的宽度
  • 很抱歉,我不清楚您所说的“在它之上”是什么意思。您的意思是“在顶部分层”(如 z 顺序)还是“朝向屏幕顶部”(如 y 坐标)?
  • @FunkTheMonk 的adjustViewBounds 是用来保持图像的纵横比的,不是吗?不过,我想在这种情况下没有必要。
  • @MikeT 对此我很抱歉;英语不是我的主要语言。我的意思是在顶部分层,就像在 z 轴上一样。 :)

标签: android view android-framelayout viewgroup


【解决方案1】:

如果您能解释更多关于您试图在布局中完成什么(不是布局本身,而是用户应该在屏幕上看到什么以及布局中的其他元素是什么),将会有所帮助。

具有多个子级的 FrameLayout 通常是“代码异味”。通常,FrameLayouts 应该只有一个子元素。所以这让我怀疑你的设计是否有问题。

-- 编辑--

如果我理解正确,您正在尝试使用框架布局来包装图像的内容,但同时匹配框架布局之前/之后其他布局视图留下的空间。

框架布局的父视图/布局是什么?

我发现此设计或您的解释存在一些问题:

  1. 您已将 framelayout 宽度设置为与父级匹配,但您想包装图像的内容。

  2. 您希望缩小图像视图,但您没有考虑线性布局中的文本视图。您将它们设置为包装内容。所以当名声布局很小的时候,你不会看到所有的文本视图。 (除非您也以某种方式调整它们的大小)。

很抱歉,如果这还不够有用,但很难理解您要通过此布局完成什么。示例用例将有助于为您提供更好的建议。

【讨论】:

  • 嗨,迈克。我添加了有关我的问题背后的推理的更多信息。感谢您提供帮助。
  • 你好迈克。感谢您花时间帮助我。我附上了 2 个正在发生的事情以及应该如何做的例子。请让我知道我还需要解释什么或从我的来源粘贴。
  • 如果没有某种类型的裁剪,您不能同时保持纵横比和匹配父级的大小。您是否尝试过移除 adjustViewBounds 并设置 scaleType?
  • 是的,我尝试删除 adjustViewBounds 并设置 scaleType="centerInside" 并没有改变布局中的任何内容(结果相同)。
  • 让我测试一下然后回复你
【解决方案2】:

当尺寸(宽/高)为MeasureSpec.EXACTLY时,adjustViewBounds 不会影响。

在您的情况下,拥有android:width="match_parent" 可确保图像视图是父级的大小,而不管adjustViewBounds。

因为高度是wrap_content,所以它开始工作 - 当图像被缩放以填充宽度时,高度会被调整。

当您覆盖高度以适应屏幕上的所有内容时(一开始这可能不是一个好主意),宽度仍然与父级匹配并且不会进行调整。然而,因为比例类型是ScaleType.FIT_CENTER,所以图像被缩放和定位,因此它的整体适合ImageView 的边界(并且居中......因此得名)。

如果您打开用于绘制布局边界的调试选项,或者使用 hierarchyviewer 查看您的应用,您会看到图像视图仍然与其父视图的宽度匹配。

您可以通过多种方式做您想做的事。 由于您已经在手动计算高度,因此设置宽度应该不会那么难。

Drawable drawable = imageView.getDrawable();
if (drawable != null && drawable.getIntrinsicWidth() > 0 && drawable.getIntrinsicHeight() > 0) {
    int height = // however you calculate it
    int width = height / (getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth());
}

你也可以逍遥法外

<ImageView
    android:id="@+id/flexible_imageview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:adjustViewBounds="true"
    android:minWidth="9999dp" />

即使这样可行,您也可能无法再使用权重在水平 LinearLayout 中使用它(例如,如果您想要布局的横向变体)或许多其他场景。

【讨论】:

    猜你喜欢
    • 2014-08-29
    • 1970-01-01
    • 2015-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    • 1970-01-01
    相关资源
    最近更新 更多