在 RelativeLayout 中控制嵌套的 ViewGroup 大小:wrap_content 仍然匹配 parent
Controlling nested ViewGroup size in a RelativeLayout: with wrap_content is still matching parent
我有一个小部件,它使用 PercentRelativeLayout 在其中放置 4 个 ImageView。我需要百分比功能,因为我将图像放在盒子的 4 个边上,但相对大小不同:顶部 child 占据了大约 60% 的高度。我已经单独预览了这个布局,效果很好,没问题。这个小部件对 w 和 h 做了 wrap_content
(我不太关心 w,但是 h 很重要,你会看到的。)
我需要在更大的布局中使用此小部件。现在我有另一个 parent RelativeLayout。这个布局应该在顶部包含所描述的小部件,然后在它下面包含一些按钮,主要是线性方式:|--(group widget)--(text button)--(image button)—-|
,其中“|”表示它应该紧贴 parent。 (这是一个 Relative 的原因是我想在右下角浮动另一个视图。)
所以目标是:这个 parent 布局的大小应该调整到某个预定义的大小(基本上是屏幕,虽然在我的完整代码中还有更多超出这个级别的 - 但我的问题发生在这个级别),2 个按钮应该计算它们的自然大小并使用它,然后顶部的 PercentRelativeLayout 应该采用“剩余”高度并将其用于其 children % 大小调整。
实际上,如屏幕截图所示(来自布局预览工具)- PercentRelativeLayout 占用了所有大小。
简而言之,您能否将一系列视图固定在一个相对布局中并拥有一个变量 child?在 iOS 中,我会将第一个视图固定在 parent 顶部,最后一个视图固定在 parent 底部,所有内容都固定在它上面的东西上,按钮有它们的固有大小,然后是我的神秘小部件吸收了剩余部分。
<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。没变。还尝试在根部使用垂直 LinearLayout。 :(
顺便说一下,图像组小部件将是一个 PercentRelativeLayout 子类,所以如果我需要通过一些覆盖来实现一些神奇的效果,我可以做到。
我了解了一些关于 RelativeLayout 野兽的知识:
- Child 大小和位置似乎齐头并进。没有尝试将大小与位置分开计算。
- RelativeLayout 似乎没有进行第二次测量。它非常贪婪:当它达到给定的 child 来决定把它放在哪里时,它会当场做出决定。也许有些情况确实如此,我不确定,但它们可能并不常见。
- 最后,将它们联系在一起的事情:如何指定关系很重要,因为 RL 计算宽度和高度的依赖顺序;因为依赖的东西首先确定大小,使用上面的贪婪 属性,如果 child 没有固定大小,它将吸收 RL 提供的任何剩余 space。因此,由于我安排的事情取决于上面的内容,而
matchPlay
是根,因此 matchPlay
首先调整大小。
因此我只是将依赖关系向后,其中的东西被固定在底部,因此 matchPlay
在依赖链中是最后一个。下面是奇怪但有效的 XML。实现的非常奇怪的方面,而且文档没有说明相关布局属性中缺乏关联性。 (显然应该如此,因为它会极大地影响您使用相对属性的方式!)
<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" />
我有一个小部件,它使用 PercentRelativeLayout 在其中放置 4 个 ImageView。我需要百分比功能,因为我将图像放在盒子的 4 个边上,但相对大小不同:顶部 child 占据了大约 60% 的高度。我已经单独预览了这个布局,效果很好,没问题。这个小部件对 w 和 h 做了 wrap_content
(我不太关心 w,但是 h 很重要,你会看到的。)
我需要在更大的布局中使用此小部件。现在我有另一个 parent RelativeLayout。这个布局应该在顶部包含所描述的小部件,然后在它下面包含一些按钮,主要是线性方式:|--(group widget)--(text button)--(image button)—-|
,其中“|”表示它应该紧贴 parent。 (这是一个 Relative 的原因是我想在右下角浮动另一个视图。)
所以目标是:这个 parent 布局的大小应该调整到某个预定义的大小(基本上是屏幕,虽然在我的完整代码中还有更多超出这个级别的 - 但我的问题发生在这个级别),2 个按钮应该计算它们的自然大小并使用它,然后顶部的 PercentRelativeLayout 应该采用“剩余”高度并将其用于其 children % 大小调整。
实际上,如屏幕截图所示(来自布局预览工具)- PercentRelativeLayout 占用了所有大小。
简而言之,您能否将一系列视图固定在一个相对布局中并拥有一个变量 child?在 iOS 中,我会将第一个视图固定在 parent 顶部,最后一个视图固定在 parent 底部,所有内容都固定在它上面的东西上,按钮有它们的固有大小,然后是我的神秘小部件吸收了剩余部分。
<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。没变。还尝试在根部使用垂直 LinearLayout。 :(
我了解了一些关于 RelativeLayout 野兽的知识:
- Child 大小和位置似乎齐头并进。没有尝试将大小与位置分开计算。
- RelativeLayout 似乎没有进行第二次测量。它非常贪婪:当它达到给定的 child 来决定把它放在哪里时,它会当场做出决定。也许有些情况确实如此,我不确定,但它们可能并不常见。
- 最后,将它们联系在一起的事情:如何指定关系很重要,因为 RL 计算宽度和高度的依赖顺序;因为依赖的东西首先确定大小,使用上面的贪婪 属性,如果 child 没有固定大小,它将吸收 RL 提供的任何剩余 space。因此,由于我安排的事情取决于上面的内容,而
matchPlay
是根,因此matchPlay
首先调整大小。
因此我只是将依赖关系向后,其中的东西被固定在底部,因此 matchPlay
在依赖链中是最后一个。下面是奇怪但有效的 XML。实现的非常奇怪的方面,而且文档没有说明相关布局属性中缺乏关联性。 (显然应该如此,因为它会极大地影响您使用相对属性的方式!)
<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" />