match_parent 未按预期执行
Posted
技术标签:
【中文标题】match_parent 未按预期执行【英文标题】:match_parent not performing as expected 【发布时间】:2013-08-20 09:51:47 【问题描述】:如果您比我更了解 XML 布局,我想这应该是一个相当容易回答的问题。在使用 match_parent layout_height 时,我似乎没有得到我所想的。
我有一个带有 android:orientation="vertical" 的 LinearLayout 根元素。在此 LinearLayout 中,我想要三个元素: - 文本视图 - 列表显示 - 文本视图
对于两个 TextView,我都设置了 android:layout_,这样它们的高度就可以显示它们的内容。问题是,我希望一个 TextView 位于表单的顶部,另一个位于表单的底部,而 ListView 会填满表单上的任何可用空间。所以这是我的 xml 布局的样子:
<TextView android:layout_ android:layout_ android:textSize="30sp" android:text="Top TextView" /> <ListView android:id="@+id/listView_Species" android:layout_ android:layout_ /> <TextView android:layout_ android:layout_ android:textSize="30sp" android:text="Bottom TextView" />
但它不起作用。这就是我得到的。我选择了 ListView 以便将其突出显示。注意它是如何一直延伸到表单底部的,将底部的 TextView 推离表单。
当我将 ListView 的 layout_height 属性更改为某个固定值时,例如 180dp,这就是表单的样子。我只是发布这个来证明底部的 TextView 在那里,但我仍然不知道如何将它固定到屏幕的底部,而 ListView 占用了剩余的任何空间,但在两个 TextView 之间。
提前致谢。
【问题讨论】:
【参考方案1】:虽然其他答案试图解决您的问题(他们实际上并没有 - 他们建议您做一些看起来相似但在不同设备上可能看起来不错也可能不好看的事情),没有人填补了您对 LinearLayouts 和 match_parent 知识的空白。而且这些差距非常普遍——Google 的文档仍然远远低于一流水平。
首先,视图如何在 LinearLayout 中工作?让我们看一下绘制LinearLayout的过程,为了简单起见,使用orientation="vertical"
。
-
检查LinearLayout的第一个孩子的高度(简称LL)。如果高度是
match_parent
或fill_parent
(同一事物的旧名称),则视图的高度将被拉伸以填充整个查看区域。如果高度为wrap_content
,则测量视图占用的垂直空间并将该空间用于视图。如果高度是一个非零数字,则使用恰好相同的像素作为视图的高度(如果太小可能会裁剪)。如果高度为 0,请参见下文。
将下一个视图低于 1 中的视图。检查其高度并采取相应措施。
继续查看所有视图。如果一个 View 被推离底部,继续并停止计算,因为没有人会看到它或任何后续的 View(假设没有 ScrollView)。
如果 View 的高度为 0,请检查它是否为 gravity
。这需要第二次通过,存储所有视图的重力,然后按比例分配它们的高度。您可以猜到,第二遍布局所需的时间加倍,这对于简单的布局来说并不重要。
您的示例说明:LL 的第一个孩子(第一个 TextView)被测量并占用一定数量的像素。然后您的 ListView 会占用所有剩余空间(通过match_parent
)。然后你的第二个 TextView 根本没有绘制,因为它不在屏幕底部。这与你观察到的差不多,但现在你明白为什么了。
解决方案:使用RelativeLayout
。在这种情况下完美运行。
<RelativeLayout
android:layout_
android:layout_>
<TextView
android:id="@+id/top_tv"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:textSize="30sp"
android:text="Top TextView" />
<TextView
android:id="@+id/bottom_tv"
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:textSize="30sp"
android:text="Bottom TextView" />
<ListView
android:id="@+id/listView_Species"
android:layout_
android:layout_
android:layout_below="@id/top_tv"
android:layout_above="@id/bottom_tv"
/>
</RelativeLayout>
RelativeLayout 告诉布局充气器在顶部绘制第一个 TextView,然后在底部绘制第二个 TextView,然后用您的 ListView 填充其余空间。我相信这正是您想要的。
欢迎使用 Android。你会经常使用这种模式!
【讨论】:
【参考方案2】:将ListView
的高度改为0dp并添加weight=1
即:
<TextView
android:layout_
android:layout_
android:textSize="30sp"
android:text="Top TextView" />
<ListView
android:id="@+id/listView_Species"
android:layout_
android:layout_
android:layout_weight="1" />
<TextView
android:layout_
android:layout_
android:textSize="30sp"
android:text="Bottom TextView" />
【讨论】:
解释这么多。叹息。【参考方案3】:使用 android:layout_weight 为最外层布局内的小部件定义权重。将它们的高度声明为0dp
,然后为它们中的每一个定义android:layout_weight
。
他们三个的总重量总和应该是1。根据您的需要,您可以将0.1
权重定义为顶部和底部TextView,并将0.8
定义为ListView。
<TextView
android:layout_
android:layout_
android:layout_weight = "0.1"
android:textSize="30sp"
android:text="Top TextView" />
<ListView
android:id="@+id/listView_Species"
android:layout_
android:layout_weight = "0.8"
android:layout_ />
<TextView
android:layout_
android:layout_
android:textSize="30sp"
android:layout_weight = "0.1"
android:text="Bottom TextView" />
【讨论】:
我赞成您的回答,但它并没有完全满足我的要求。这会导致 TextViews 也拉伸到屏幕大小的某个百分比。我希望在只有 ListView 伸展以占用剩余空间时修复这些问题。上面的 Royi,发布了解决方案。以上是关于match_parent 未按预期执行的主要内容,如果未能解决你的问题,请参考以下文章