在理解 Android XML 中的 layout_weight 属性方面存在问题。

17

我真的尝试过,但是我不明白Android如何解释layout_weight设置...

我想实现的是:

  • 一个位于顶部且高度固定的标题
  • 一个包含EditText和Button的底部输入区域
  • 中间的内容部分占据所有剩余的空间

在输入时,我希望EditText增长到特定的高度,并在输入的文本超出可用高度时开始滚动。为此,我需要周围的LinearLayout与EditText一起增长。

如果我为内部的LinearLayout定义特定的高度,它就不会增长。如果我不这样做,无论我使用什么layout_weight都会导致内部布局占据全部空间而不是ScrollView。:(

我的当前XML看起来像这样:

<LinearLayout 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_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="I'm a header" />
    <ScrollView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:gravity="bottom">
        <LinearLayout
            android:id="@+id/itemContainer"
            android:orientation="vertical"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />
    </ScrollView>
    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:padding="2dp"
        android:gravity="bottom"
        android:isScrollContainer="true"
        android:background="@drawable/steel" >
        <EditText
            android:id="@+id/edittext01"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.2"
            android:scrollbars="vertical"
            android:fadingEdge="vertical"
            android:fadingEdgeLength="60dp"
            android:maxHeight="40dp"
            android:textSize="15sp" />
        <Button
            android:id="@+id/button"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0.8"
            android:layout_gravity="right"
            android:text="Send"
            android:textStyle="bold"
            android:textSize="15sp" />
    </LinearLayout>
</LinearLayout>

非常感谢任何建议!

4个回答

38

layout_weight 用于确定 Android 在各个小部件获得它们想要的所有空间后,如何划分剩余的空间。

假设有三个小部件排成一行,每个小部件都想要 10 个像素,但是你有 50 个像素的空间。以下是几个 layout_weight 的示例和每个小部件将要占用的像素数:

widget1: weight = 1, 30px
widget2: weight = 0, 10px
widget3: weight = 0, 10px

widget1: weight = 1, 20px
widget2: weight = 1, 20px
widget3: weight = 0, 10px

widget1: weight = 1, 16.5px
widget2: weight = 1, 16.5px
widget3: weight = 1, 16.5px

你可以将权重视为可用空间的百分比。 它将累加所有值,然后根据需要分发部分。 因此,如果有帮助的话,您可以使用加起来为100的权重来表示百分比:

widget1: weight = 0, 10px
widget2: weight = 25, 15px
widget3: weight = 75, 25px

如果我理解正确,您希望底部小部件从特定大小开始,必要时扩展至某个最大大小,然后滚动。

而且,您希望上面的小部件接管所有额外的空间。

不幸的是,在Android上无法真正指定最大的大小。我认为您能做的最好的就是给ScrollView一些固定的大小,使用layout_weight=1,并告诉下面的LinearLayout使用wrap_content。这将导致LinearLayout扩展直到它无法再扩展,因为ScrollView已经占用了空间。

但是,挑战在于指定一个对所有不同屏幕大小和分辨率都有意义的固定大小的ScrollView。您可能最终需要为不同的分辨率创建不同的布局,这可能不值得。就我个人而言,我只会给editText设置一个固定的大小...


谢谢Mayra。这正是我想做的。也许kcoppock有其他想法。如果必须这样做,我将最终为不同的解决方案创建布局。:( 将ScrollView设置为特定大小并添加layout_weight = 1会导致ScrollView占用所有可用空间,并在其他小部件占用更多空间时“缩小”到其定义的大小,对吗? - Dennis Winter
1
没问题。我相信EditTexts有一个setMultiLine属性。如果你设置它,并将高度设置为wrap_content,我相当确定它会展开以适应并缩小ScrollView。 - Kevin Coppock
嘿Mayra!我尝试了各种版本的设置ScrollView、LinearLayout等特定大小和layout_weight=1的方法,但是增长的EditText甚至会在继续输入时超出屏幕!你认为我完全走错了吗?!没想到要花几个小时在这上面... ;) - Dennis Winter
如果在EditText上设置了特定的大小,它是否会滚动? - Cheryl Simon
Mayra,如果我将layout_height设置为特定的高度,它会滚动,并且设置scrollbars="vertical",然后显示滚动条。我想我会使用DisplayMetrics计算EditText的合适高度。感谢您的帮助! - Dennis Winter
显示剩余3条评论

3

我遇到了类似的问题(页脚带有刷新时间戳固定在屏幕底部,而ListView/ScrollView占据了所有剩余空间),经过多次尝试,我使用以下布局成功解决:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent">

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" 
              android:layout_above="@+id/refresh_date_text" 
              android:layout_alignParentTop="true"
              android:orientation="vertical" 
              >

    <ListView android:id="@android:id/list" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:background="#FFFFFF"
        android:layout_weight="1" android:divider="@drawable/list_divider"
        android:dividerHeight="1dp" android:drawSelectorOnTop="false" />

    <TextView android:id="@android:id/empty"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:background="#ffffff"
              android:gravity="center_horizontal"
              android:paddingTop="10dp"
              android:text="The list is empty."/>

</LinearLayout>

<TextView android:id="@+id/refresh_date_text"
          android:layout_width="match_parent" 
          android:layout_height="wrap_content" 
          android:layout_alignParentBottom="true"
          android:gravity="center_horizontal" 
          android:background="#f0f0f0" 
          android:textStyle="italic" 
          android:textSize="12dp"
          />
</RelativeLayout>

不要裁剪ListView,使用滚动条,在所有方向上对齐完美,正确显示“列表为空”的文本。

1

我认为你最好使用RelativeLayout。添加你的标题,将其设置为layout_alignParentTop="true"。然后添加你的EditText和Button,将该区域设置为layout_alignParentBottom="true"。接下来,添加中心区域,将宽度和高度设置为fill_parent,并设置layout_above="{EditText/Button布局的id}"layout_below="{标题布局的id}"

我在工作中没有Eclipse,否则我会为你测试一下,但这应该可以工作。


非常感谢,kcoppock!我会在一两个小时内测试它,并告诉您它是否有效。 - Dennis Winter
你能否将你尝试过的代码发布到pastebin.com链接上?或者直接编辑到原始帖子中?我可以看一下,看看是否有什么问题。哦,还有,布局权重应该只是整数。如果我没记错的话,所有定义的layout_weights应该加起来为10。所以2的权重就是20%。不过我可能记错了。 - Kevin Coppock
我已经尝试过了。我所做的仅仅是将页脚放在ScrollView之前,这样就可以被找到并使Eclipse编译。 现在页眉也出现了,但是页脚仍然占据了屏幕的50%,将按钮和EditText与其顶部对齐。我有一种感觉整个结构都是正确的,但内部LinearLayout可能有问题。非常感谢您迄今为止的帮助! :) - Dennis Winter
太酷了,谢谢!一旦我弄清楚如何使用滚动容器,我会告诉你的!;) - Dennis Winter
我有完全相同的问题,而且它确实与背景有关,你所说的“强制小部件保持其大小”是什么意思?谢谢。 - StJimmy
显示剩余6条评论

-1
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:weightSum="1"
>
<TextView
 android:text=" TextView " 
 android:textColor="#ffffff"
 android:textSize="15sp"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:background="#ff0000"
 />
 <EditText
  android:text=" EditText " 
  android:textSize="15sp"
  android:layout_width="250dp"
  android:layout_weight="1"
  android:layout_height="0dp"
  />
 <Button
    android:text=" button " 
    android:textColor="#000000"
    android:textSize="15sp"
    android:gravity="center_vertical|center_horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />
  </LinearLayout>

这将有所帮助


没有冒犯之意,也许我只是不理解你在尝试使用这个 XML 做什么,但我无法看出它如何有助于解决最初的问题。你能否稍微澄清一下? - Dennis Winter

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