【问题标题】:Controlling nested ViewGroup size in a RelativeLayout: with wrap_content is still matching parent控制 RelativeLayout 中的嵌套 ViewGroup 大小:使用 wrap_content 仍然匹配父级
【发布时间】:2016-09-12 22:07:42
【问题描述】:

我有一个小部件,它使用 PercentRelativeLayout 在其中放置 4 个 ImageView。我需要百分比特征,因为我将图像放在盒子的 4 个边上,但相对大小不同:顶部的孩子占据了大约 60% 的高度。我已经自己预览了这个布局,效果很好,没问题。这个小部件为 w 和 h 执行 wrap_content(w 我不太关心,但 h 很重要,正如您将看到的那样。)

我需要在更大的布局中使用这个小部件。现在我有另一个父RelativeLayout。此布局应在顶部包含所描述的小部件,然后在其下方包含一些按钮,以大多数线性方式:|--(group widget)--(text button)--(image button)—-|,其中“|”表示它应该紧贴父级。 (这是一个相对的原因是我想在右下角浮动另一个视图。)

所以目标是:这个父布局应该被调整到某个预定义的大小(基本上是屏幕,虽然在我的完整代码中还有更多高于这个级别 - 但我的问题只是在这个级别上发生隔离),2按钮应该计算它们的自然大小并使用它,然后顶部的 PercentRelativeLayout 应该采用“剩余”高度并将其用于其子元素的 % 大小。

实际上,如屏幕截图所示(来自布局预览工具)- PercentRelativeLayout 吸收了所有大小。

简而言之,您能否将一系列视图固定在一个相对布局中并拥有一个可变子项?在 iOS 中,我会将第一个视图固定到父顶部,最后一个视图固定到父底部,以及上面的所有内容,按钮具有其固有大小,然后我的神秘小部件吸收其余部分。

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#f2dce8ff"
android:layout_marginTop="8dp"
xmlns:android="http://schemas.android.com/apk/res/android">

<android.support.percent.PercentRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    xmlns:tools="http://schemas.android.com/tools"
    android:animateLayoutChanges="true"
    android:id="@+id/matchPlay">

    <ImageView
        android:src="@drawable/model_2"
        tools:background="#954f47"
        app:layout_heightPercent="59%"
        app:layout_aspectRatio="100%"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView1"
        android:scaleType="centerInside" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#ff0000"
        app:layout_heightPercent="20%"
        app:layout_aspectRatio="100%"
        app:layout_marginTopPercent="2%"
        android:layout_below="@id/avatarView1"
        android:layout_alignParentLeft="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView2"
        android:scaleType="centerCrop" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#00ff00"
        app:layout_heightPercent="20%"
        app:layout_aspectRatio="100%"
        app:layout_marginTopPercent="2%"
        android:layout_below="@id/avatarView1"
        android:layout_alignParentRight="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView3"
        android:scaleType="centerCrop" />
    <ImageView
        android:src="@drawable/model_2"
        tools:background="#0000ff"
        app:layout_heightPercent="22%"
        app:layout_aspectRatio="100%"
        android:layout_below="@id/avatarView2"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="false"
        android:id="@+id/avatarView4"
        android:scaleType="centerCrop" />

</android.support.percent.PercentRelativeLayout>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/matchplay_add_shout"
    android:id="@+id/shoutButton"
    android:enabled="false"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/matchPlay" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/submitButton"
    android:src="@drawable/matchplay_submit"
    android:layout_centerHorizontal="true"
    android:layout_below="@id/shoutButton"
    android:minWidth="50dp"
    android:contentDescription="@string/matchplay_send_contentdesc" />

<ImageButton
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/passButton"
    android:src="@drawable/matchplay_pass"
    android:layout_alignParentEnd="true"
    android:layout_alignParentBottom="true"
    android:contentDescription="@string/matchplay_pass_contentdesc" />

编辑:我更新了这段代码以不使用 alignParentBottom,认为这是关键问题;我改为使用 alignParentTop。不用找了。还尝试在根部使用垂直线性布局。 :(

顺便说一下,图像组小部件将是一个 PercentRelativeLayout 子类,所以如果我需要在那里通过一些覆盖来创造一些魔法,我可以这样做。

【问题讨论】:

    标签: android android-layout android-relativelayout android-percentrelativelayout


    【解决方案1】:

    我学到了一些关于 RelativeLayout 野兽的东西:

    • 孩子的大小和位置似乎齐头并进。没有尝试与位置分开计算大小。
    • RelativeLayout 似乎没有进行第二次测量。这是相当贪婪的:当它到达给定的孩子决定把它放在哪里时,它会在那里做出决定。也许在某些情况下确实如此,我不确定,但它们可能并不常见。
    • 最后,将它们联系在一起的东西:如何指定关系很重要,因为 RL 计算宽度和高度的依赖顺序;因为依赖的东西首先被确定大小,使用上面的贪婪属性,如果那个孩子没有固定的大小,它将吸收 RL 提供的任何剩余空间。因此,由于我根据上面的内容安排事情并且matchPlay 是根,因此首先确定matchPlay 的大小。

    因此,我只是将依赖项向后设置,将事物固定在底部,因此 matchPlay 是依赖项链中的最后一个。下面是奇怪但功能正常的 XML。实现的非常奇怪的方面,而且文档没有说明相对 layout_attrs 缺乏关联性。 (显然应该,因为它会极大地影响您使用相对属性的方式!)

    <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#f2dce8ff"
    android:layout_marginTop="8dp"
    xmlns:android="http://schemas.android.com/apk/res/android">
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/matchplay_add_shout"
        android:id="@+id/shoutButton"
        android:layout_above="@+id/submitButton"
        android:layout_marginTop="15dp"
        android:layout_centerHorizontal="true"
        android:enabled="false" />
    
    <ImageButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/submitButton"
        android:src="@drawable/matchplay_submit"
        android:minWidth="50dp"
        android:contentDescription="@string/matchplay_send_contentdesc" />
    
    <android.support.percent.PercentRelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/shoutButton"
        xmlns:tools="http://schemas.android.com/tools"
        android:animateLayoutChanges="true"
        android:id="@+id/matchPlay">
    
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#954f47"
            app:layout_heightPercent="60%"
            app:layout_aspectRatio="100%"
            app:layout_marginBottomPercent="2%"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView1"
            android:scaleType="centerInside" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#ff0000"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_below="@id/avatarView1"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView2"
            android:scaleType="centerCrop" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#00ff00"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_below="@id/avatarView1"
            android:layout_alignParentRight="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView3"
            android:scaleType="centerCrop" />
        <ImageView
            android:src="@drawable/model_2"
            tools:background="#0000ff"
            app:layout_heightPercent="23%"
            app:layout_aspectRatio="100%"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:adjustViewBounds="false"
            android:id="@+id/avatarView4"
            android:scaleType="centerCrop" />
    
    </android.support.percent.PercentRelativeLayout>
    
        <ImageButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/passButton"
            android:src="@drawable/matchplay_pass"
            android:layout_alignParentRight="true"
            android:layout_alignParentBottom="true"
            android:contentDescription="@string/matchplay_pass_contentdesc" />
    

    【讨论】:

    • 另外,我要指出的是,将avatarView4 中的layout_alignParentBottom 更改为layout_below="@id/avatarView2" 仍然会产生不好的结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-12
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    • 2014-11-04
    • 2014-03-16
    相关资源
    最近更新 更多