如何使用View填充剩余空间来创建布局?

220
我正在设计我的应用程序UI。我需要一个布局看起来像这样: (<和>是按钮)。问题是,我不知道如何确保TextView填充剩余的空间,同时两个按钮具有固定大小。
如果我为Text View使用fill_parent,则第二个按钮(>)无法显示。
如何创建一个类似于图片的布局?

你使用什么作为根布局? - woodshy
1
@woodshy 任何布局都可以,无所谓。 - Luke Vo
12个回答

250

来自woodshy的答案对我有用,而且比Ungureanu Liviu的答案更简单,因为它不使用RelativeLayout。 以下是我提供的布局以便清晰明了:

<LinearLayout 
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:orientation="horizontal"
      >

     <Button
        android:layout_width = "80dp"
        android:layout_weight = "0"
        android:layout_height = "wrap_content"
        android:text="&lt;"/>
     <TextView
        android:layout_width = "fill_parent"
        android:layout_height = "wrap_content"
        android:layout_weight = "1"/>
     <Button
        android:layout_width = "80dp"
        android:layout_weight = "0"
        android:layout_height = "wrap_content"
        android:text="&gt;"/>   
 </LinearLayout>

有一些像alignLeftalignParentLeft等的东西,是无法通过LinearLayout实现的。 - IcyFlame
我不完全理解这是如何实现的,但这确实是一个避免使用RelativeLayout的很酷的技巧。 - a.dibacco
3
这怎么可能是被接受的答案?它没有图像视图,只是解决方案的一部分。至少比旧的得票最高的相对布局答案好(我在我的答案中解释了原因)。 - Livio

99
如果将< TextView >放置在 LinearLayout 中,则应将<> Layout_weight 属性设置为0和1,以便于 TextView 的显示。
如果您正在使用 RelativeLayout ,请将<>向左和向右对齐,并将TextView的“Layout to left of”和“Layout to right of”属性设置为<>的ID。

2
还有人需要样例吗? - woodshy
如何在此布局中添加图像以填充整个视图 - Tushar Pandey
7
是的,一个样品仍然会很有帮助。 - Frank Schwieterman
1
这让人难以理解的是“<和>”,它们引用了原始帖子术语。这意味着标签为“<”和“>”的按钮分别是什么。 - Farrukh Najmi
1
@woodshy的例子会让它更好,不是吗? - Steve Moretz
显示剩余6条评论

73

如果您使用 RelativeLayout,您可以像这样做:

<RelativeLayout
    android:layout_width = "fill_parent"
    android:layout_height = "fill_parent">
    <ImageView
        android:id = "@+id/my_image"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_alignParentTop ="true" />
    <RelativeLayout
        android:id="@+id/layout_bottom"
        android:layout_width="fill_parent"
        android:layout_height = "50dp"
        android:layout_alignParentBottom = "true">
        <Button
            android:id = "@+id/but_left"
            android:layout_width = "80dp"
            android:layout_height = "wrap_content"
            android:text="&lt;"
            android:layout_alignParentLeft = "true"/>
        <TextView
            android:layout_width = "fill_parent"
            android:layout_height = "wrap_content"
            android:layout_toLeftOf = "@+id/but_right"
            android:layout_toRightOf = "@id/but_left" />
        <Button
            android:id = "@id/but_right"
            android:layout_width = "80dp"
            android:layout_height = "wrap_content"
            android:text="&gt;"
            android:layout_alignParentRight = "true"/>
    </RelativeLayout>
</RelativeLayout>

谢谢,它可以工作 :) 但我不理解。为什么TextView没有填满所有的空间,而是>按钮? - Luke Vo
2
为什么要使用两个嵌套的相对布局?根布局应该足够了。然后,您只需要确保底部相对布局的子项都是alignParentBottom="true"即可。 - Noel
@Noel 你说得对。我选择了两个布局,因为这是我习惯的方式:在我的应用程序中,可能需要更改一些视图的可见性,将它们全部放在一个布局中,并仅为此布局更改可见性更容易。我的示例不完美,但它可以工作,并且对某些人可能有用。 - Ungureanu Liviu
1
@W.N 这对我来说也很奇怪 :) 我认为TextView没有使用所有的空间,因为右侧按钮有固定的宽度。如果你将android:layout_width = "80dp"更改为android:layout_width = "wrap_content",右侧按钮就可以正常工作了。 - Ungureanu Liviu
@UngureanuLiviu 提出了一个很好的观点。当使用wrap_content时,有没有解决方案可以使TextView填充剩余空间? - Cumulo Nimbus
2
这个答案真的很糟糕!你应该避免嵌套两个相对布局,因为相对布局总是需要进行两次绘制(而其他类型的布局只需要一次)。当你嵌套它们时,会变得指数级增长。你应该在要填充剩余空间的元素上使用宽度为0且权重为1的线性布局。记住:只有在没有其他选择的情况下才使用相对布局。 - Livio

36

使用 ConstraintLayout,我发现类似以下的问题:

<Button
    android:id="@+id/left_button"
    android:layout_width="80dp"
    android:layout_height="48dp"
    android:text="&lt;"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<TextView
    android:layout_width="0dp"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toRightOf="@+id/left_button"
    app:layout_constraintRight_toLeftOf="@+id/right_button"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/right_button"
    android:layout_width="80dp"
    android:layout_height="48dp"
    android:text="&gt;"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

有效的关键是适当地设置右、左、上和下边缘约束,然后将宽度和高度设置为0dp并使其自行确定大小。


8
刚开始使用ConstraintLayout,很高兴知道当将宽度和高度设置为“0”时,它们可以通过约束来确定, 谢谢 :) - MQoder
重要的是要注意每个约束箭头的方向。确保TextView具有左右约束。如果第一个ButtonTextView具有右约束,最后一个ButtonTextView具有左约束,则TextView不会被拉伸。 - Manuel
非常好!通过避免嵌套布局,可以提高性能。感谢您提醒我们使用0dp技巧。 - OzzyTheGiant

8

这很简单,您可以根据需要设置minWidth或minHeight,取决于您是想要水平还是垂直布局。对于另一个对象(您想要填充其余空间的对象),您可以将其权重设置为1(将宽度设置为包装其内容),这样它就会填充剩余的区域。

<LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:gravity="center|left"
        android:orientation="vertical" >
</LinearLayout>
<LinearLayout
        android:layout_width="80dp"
        android:layout_height="fill_parent"
        android:minWidth="80dp" >
</LinearLayout>

6

您可以使用高的layout_weight属性。下面是一个布局示例,其中ListView占用所有可用空间,底部有按钮:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    tools:context=".ConfigurationActivity"
    android:orientation="vertical"
    >

        <ListView
            android:id="@+id/listView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_weight="1000"
            />


        <Button
            android:id="@+id/btnCreateNewRule"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Create New Rule" />



        <Button
            android:id="@+id/btnConfigureOk"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Ok" />


</LinearLayout>

5

应避免嵌套两个相对布局,因为相对布局在绘制时始终需要进行2次遍历(而其他类型的布局只需要1次)。当您嵌套它们时,这种复杂度会呈指数级增长。您应该在要填充剩余空间的元素上使用宽度为0且权重为1的线性布局。

这种做法更加高效和规范。请记住:仅在没有其他选择时使用相对布局。

<?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="match_parent"
          android:orientation="vertical">

    <ImageView
        android:id="@+id/imageview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/prev_button"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:text="&lt;" />

        <TextView
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:singleLine="true"
            android:gravity="center"
            android:text="TextView" />

        <Button
            android:id="@+id/next_button"
            android:layout_width="80dp"
            android:layout_height="wrap_content"
            android:text="&gt;" />
    </LinearLayout>
</LinearLayout>

3

如果您遇到与我相同的<LinearLayout...>问题:

重要的是要指定android:layout_width="fill_parent",而不是wrap_content

另一方面,您可以省略android:layout_weight="0",它并非必需的。

我的代码基本上与https://dev59.com/SW015IYBdhLWcg3w6QLA#25781167中的Vivek Pandey的代码相同。


1
使用相对布局时,您可以通过将视图锚定到其应向两个视图伸展的视图来使其伸展。尽管指定的高度将被忽略,但Android仍需要一个高度属性,这就是我写“0dp”的原因。例如:
<View
    android:id="@+id/topView"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:layout_alignParentTop="true"
    android:layout_marginTop="8dp"/>

<View
    android:id="@+id/stretchableView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_below="@id/topView"
    android:layout_above="@+id/bottomView"
    android:layout_marginTop="8dp"
    android:layout_marginBottom="8dp"
    android:adjustViewBounds="true"/>

<View
    android:id="@id/bottomView"
    android:layout_width="wrap_content"
    android:layout_height="40dp"
    android:layout_alignParentBottom="true"
    android:layout_marginBottom="16dp"/>

0

您可以使用设置layout_widthlayout_height0dp(根据您想要填充剩余空间的方向)。 然后使用layout_weight来使其填充剩余空间。


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