LinearLayout: layout_gravity="bottom"在水平LinearLayout上无效

51

首先,我已经在整个互联网上搜索了一遍,但是没有人有类似的问题。所以,我想要的只是拥有3个textView,底部对齐屏幕,并且宽度相同。下面是一个代表我的需求的图像:

enter image description here

这是我的代码:

 <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent">
 <LinearLayout 
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true">

      <TextView 
           android:text="@string/help_1"
           android:layout_weight="0.33"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="@drawable/mynicebg1"

           android:layout_gravity="bottom"/>

      <TextView 
           android:text="@string/help_2"
           android:layout_weight="0.33"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="@drawable/mynicebg2"

           android:layout_gravity="bottom"/>

      <TextView 
           android:text="@string/help_3"
           android:layout_weight="0.33"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="@drawable/mynicebg3"

           android:layout_gravity="bottom"/>

 </LinearLayout>
 </RelativeLayout>

当三个textView的高度相同时,它是有效的,但当它们的大小不同时,会得到以下结果:

problem

另一个奇怪的行为是,当我将最大文本的layout_gravity设置为"center-vertical"时,我会得到以下结果:

first workaround

显然,我变得疯狂并尝试了其他与center-vertical的组合,但没有像最初想的那样工作:

desperation workaround

那么,有什么解决方法吗?

7个回答

115

正确的答案

所有其他答案都是错误的。重点如下:

  1. 不需要使用RelativeLayout,只需使用LinearLayout即可。
  2. (不是必要的,但我猜你不知道)您的权重不需要加起来等于1,您可以将它们全部设置为任何相等的值(例如1)。
  3. 关键是需要android:baselineAligned="false"。我实际上是通过查看LinearLayout源代码才发现这一点。它在文档中,但他们没有提到它是默认打开的!

无论如何,以下是代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:baselineAligned="false">
      <TextView 
           android:text="dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg dfg"
           android:layout_weight="1"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#eeffee"
           android:layout_gravity="bottom"/>

      <TextView 
           android:text="asd asd asd asd asd asd asd asd asd asd"
           android:layout_weight="1"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#eeeeff"
           android:layout_gravity="bottom"/>


      <TextView 
           android:text="qweoiu qweoiuqwe oiqwe qwoeiu qweoiu qweoiuq weoiuqw eoiquw eoiqwue oqiweu qowieu qowieu qoiweu qowieu qowieu qowieu qowieu qoiweu qowieu qoiwue "
           android:layout_weight="1"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#ffeeee"
           android:layout_gravity="bottom"/>

 </LinearLayout>

它是这样的:

好的线性布局


1
一个非常简单的修复方法,对我立即有效。我希望在当前被接受的答案之前就读到了这个。 - bgolson
@Timmmm 我有自己的TextView实现,扩展了TextView。你提供的“baseAligned”的解决方案对我不起作用。请猜测一下问题出在哪里? - Shirish Herwade
不好意思,我不知道。建议您查看LinearLayout的代码,了解它如何使用baselineAligned,并检查您的代码是否覆盖了其方法。您使用的是baselineAligned而不是baseAligned,对吧? - Timmmm

4
好的。所以我遇到同样的问题,但是是针对切换按钮而不是文本视图。由于某种原因,如果LinearLayout(水平)中的一个元素与布局中其余视图的高度不同,并且被设置为具有与其他元素相同的重力,则重力实际上会“被忽略”。
通过将每个视图包装在RelativeLayout中并在相对布局上设置android:gravity而不是在每个按钮上设置android:layout_gravity,我成功地使行为符合预期。 我还将android:layout_weight从按钮移到了相对布局中。
所以我现在的布局是:
<LinearLayout
  ... >
    <ToggleButton
        ...
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:layout_gravity="bottom"/>


    <ToggleButton
        ...
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:layout_gravity="bottom"/>

    <ToggleButton
        ...
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:layout_weight="1"
        android:layout_gravity="bottom"/>
</LinearLayout>

出现了与之前报告的相同问题,我改为:

<LinearLayout
  ... >
    <RelativeLayout
        ...
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="bottom" >

        <ToggleButton
            ...
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            />

    <RelativeLayout
        ...
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="bottom" >

        <ToggleButton
            ...
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
           />      

    <RelativeLayout
        ...
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="bottom" >

        <ToggleButton
            ...
            android:layout_height="wrap_content"
            android:layout_width="fill_parent"
            />
</LinearLayout>

这就是我最终解决它的方法。我在一个LinearLayout内部的ScrollView(另一个LinearLayout内部)放置了一个按钮。直到我将该按钮放入另一个LinearLayout中,该按钮才能与底部对齐。 - gdawgrancid

1

**编辑:

如果此方法无法实现所有功能,请按照下面 Timmmmm 的回答中提到的使用基线对齐标志(baselinealigned flag)。那是更好的方法。

使用此代码

已编辑布局:好的,我已经编辑了它并添加了颜色和重力,以使底部的文本视图具有相等的高度和宽度,并将每个视图的文本对齐于底部和居中。

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:gravity="fill_vertical" >

        <TextView  
            android:layout_width="match_parent" 
            android:layout_height="match_parent"
            android:layout_weight="1.0"
            android:layout_gravity="fill_vertical"
            android:gravity="bottom|center"
            android:text="text1 jkjhh  jhguk jvugy v ghjv  kjhvygvusdioc jgytuayhashg hgyff"
            android:textColor="#000000"
            android:background="#FFFF00"
            />
        <TextView  
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:layout_weight="1.0"
            android:layout_gravity="fill_vertical"
            android:gravity="bottom|center"
            android:text="t2"
            android:textColor="#000000"
            android:background="#FF0000"
            />      
        <TextView  
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:layout_weight="1.0"
            android:layout_gravity="fill_vertical"
            android:gravity="bottom|center"
            android:text="This is a long text. This is a long text. This is a long text. This is a long text.This is a long text. This is a long text. This is a long text."
            android:textColor="#000000"
            android:background="#00FF00"
            />
    </LinearLayout>

它应该完全按照您的要求执行。

它在RelativeLayout内部使用LinearLayout,但有时需要将它们嵌套以获得所需内容。在相对布局中添加任何其他视图,并始终使您的文本位于底部,只要RelativeLayout中的最后一个子项是如上所示的LinearLayout即可。


我通过将重力设置为中心进行了测试,就像我展示的那样,它们很好地工作。我可能没有理解您尝试对齐它们的方式。您能描述一下吗? - achie
你的文本必须有多行。我的第一段有5行,第二段有3行,最后一段有7行。我试图在图片上表示它,但我不能提交应用程序的截图,因为我的雇主不会喜欢。 - Paulo Cesar
好的,在这种情况下,将每个TextView的layout_height设置为match_parent。我还修改了上面的代码,请检查它并确认是否有效。 - achie
@Paulo Cesar:我已经编辑了代码,按照你的要求安排了布局。我进行了测试,并为每个TextView添加了颜色。如果这不是你想要的,请告诉我。 - achie
找到了一个解决方法!我在LinearLayout里面放了一个RelativeLayout,然后把TextView放在RelativeLayout里面。这不是永久性的解决方案,因为它只有在我知道哪个文本是最大的时候才能起作用。 - Paulo Cesar
显示剩余4条评论

1
与Timmm的答案相同,但您也可以使用android:gravity="bottom"替代每个TextViewandroid:layout_gravity="bottom"属性,用于LinearLayout属性。

像这样:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      android:gravity="bottom"
      android:baselineAligned="false">
      <TextView 
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:text="your text 1......"
           android:layout_weight="1"/>

      <TextView 
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:text="your text 2......"
           android:layout_weight="1"/>

      <TextView 
           android:layout_width="0dp"
           android:layout_height="wrap_content"
           android:text="your text 3......"
           android:layout_weight="1"/>

</LinearLayout>

感谢您的编辑,TheEsisia。我没有任何经验 :) - sweet-2

0
如果你不介意使用RelativeLayout而不是LinearLayout,我猜这个方法可以解决问题:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/LinearLayout1"
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView android:layout_height="wrap_content"
    android:layout_width="fill_parent" android:text="@string/hello"
    android:id="@+id/TextView1" android:layout_above="@+id/TextView2"
    android:layout_alignLeft="@+id/TextView2"></TextView>

<TextView android:layout_height="wrap_content"
    android:layout_width="fill_parent" android:text="@string/hello"
    android:id="@+id/TextView2" android:layout_alignParentBottom="true">  </TextView>

</RelativeLayout>

但是使用RelativeLayout时,我无法使用android:layout_weight="0.33"来使所有的textView大小相同...除非有更好的方法让它们大小相同? - Paulo Cesar
在最坏情况下,您可以使用DIP值来调整宽度或高度以使它们达到相同的大小,但我不确定是否完全理解您在这里要解决的问题... - Dominik Helleberg
指定值对我没用,我希望它们根据父元素的宽度自动调整... - Paulo Cesar

0
一个更简单的解决方案是使用<Space>标签:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="wrap_content">

      <Space
           android:layout_width="0dp"
           android:layout_height="1dp"
           android:layout_weight="1" />

      <TextView 
           android:text="Any Text"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#eeffee"/>

      <TextView 
           android:text="Any Text2"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#eeeeff"/>


      <TextView 
           android:text="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="#ffeeee"/>

 </LinearLayout>

0
如果您想让三个子视图的高度相同,则将高度更改为“0”,将LinearLayout的android:weightSum设置为3,并将每个视图的android:layout_weight设置为1。

哦,我不希望它们有相同的高度。我希望它们有相同的宽度。 - Paulo Cesar
你是想要水平地还是垂直地堆叠它们? - Gallal
抱歉,我的问题标题写错了,我想要将它们水平排列。对于造成的困扰,我感到非常抱歉。 - Paulo Cesar
然后将LinearLayout的方向设置为水平,权重总和设置为3,并且对于每个子视图,将视图的高度设置为match_parent,宽度设置为0,布局权重设置为1。 - Gallal
好的,我按照你说的做了。现在TextViews已经正确对齐了,但是它们都有相同的高度。但我不想让它们有相同的高度... - Paulo Cesar
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接