218

I'm designing my application UI. I need a layout looks like this:

Example of desired layout

(< and > are Buttons). The problem is, I don't know how to make sure the TextView will fill the remaining space, with two buttons have fixed size.

If I use fill_parent for Text View, the second button (>) can't be shown.

How can I craft a layout that looks like the image?

CJBS
  • 15,147
  • 6
  • 86
  • 135
Luke Vo
  • 17,859
  • 21
  • 105
  • 181

12 Answers12

248

Answer from woodshy worked for me, and it is simpler than the answer by Ungureanu Liviu since it does not use RelativeLayout. I am giving my layout for clarity:

<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>
Vivek Pandey
  • 3,455
  • 1
  • 19
  • 25
  • There are somethings like `alignLeft` and `alignParentLeft`, etc, which can never be achieved with `LinearLayout`. – IcyFlame Jun 28 '16 at 07:23
  • I don't fully understand how this is possible but it is really cool trick to avoid RelativeLayout – a.dibacco Jan 19 '17 at 21:11
  • 3
    How can this be the accepted answer ? There is no image view, it's only part of the solution. At least it's better than the old top voted answer with Relative Layout (I explained why in my answer) – Livio Oct 07 '17 at 17:27
98

If <TextView> is placed in a LinearLayout, set the Layout_weight proprty of < and > to 0 and 1 for the TextView.

If you're using a RelativeLayout, align < and > to the left and right and set "Layout to left of" and "Layout to right of" property of the TextView to the ids of < and >.

ggorlen
  • 44,755
  • 7
  • 76
  • 106
woodshy
  • 4,085
  • 3
  • 22
  • 21
73

If you use RelativeLayout, you can do it something like this:

<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>
Allan Pereira
  • 2,572
  • 4
  • 21
  • 28
Ungureanu Liviu
  • 4,034
  • 4
  • 37
  • 42
  • Thanks, it works :) But I don't understand. Why don't the TextView fill all the space, not for the `>` button? – Luke Vo Jun 11 '11 at 15:09
  • 2
    Why have two nested relative layouts? The root one should be sufficient. Then, all you need to do is ensure that the children of the bottom relative layout are all alignParentBottom="true" – Noel Jun 11 '11 at 15:10
  • @Noel You're right. I choose 2 layout because this is the way I'm used: in my applications it can happen that I need to change visibility of a few views and it is easier to put all of them in a layout and change the visibility just for this layout. My example is not perfect but it works and it might be usefull for someone. – Ungureanu Liviu Jun 11 '11 at 15:48
  • 1
    @W.N This is stange for me too :) I think the textview don't use all the space because the right button have a fixed width. If you change the android:layout_width = "80dp" to android:layout_width = "wrap_content" for right button it whould work. – Ungureanu Liviu Jun 11 '11 at 15:51
  • @UngureanuLiviu makes a good point. Is there a solution to have the TextView fill the remaining space when wrap_content is used?? – Cumulo Nimbus May 21 '14 at 18:23
  • 2
    This answer is really bad! You should avoid nesting 2 relative layout since relative layout always make 2 pass for drawing (against 1 for any other type of layout). It becomes exponential when you nest them. You should use linear layout with width=0 and weight=1 on the element you want to fill the space left. Remember: use relative layout ONLY when you don't have other choice. http://stackoverflow.com/questions/4069037/android-is-a-relativelayout-more-expensive-than-a-linearlayout – Livio Nov 05 '15 at 10:35
36

Using a ConstraintLayout, I've found something like

<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" />

works. The key is setting the right, left, top, and bottom edge constraints appropriately, then setting the width and height to 0dp and letting it figure out it's own size.

Tom Howard
  • 4,672
  • 2
  • 43
  • 48
  • 8
    Just starting using ConstraintLayout, its great to know that the width and height can be determined by constraints when setting them to "0", Thanx for that :) – MQoder Feb 28 '18 at 12:58
  • Important to be careful about the *direction* of the arrow of each constraints. Make sure that `TextView` has the left and right constraints. The `TextView` does not stretch if the first `Button` has the right constraint to the `TextView` and the last `Button` has the left constraint to the `TextView`. – Manuel May 28 '19 at 01:45
  • much better! improves performance by not having nested layouts. Thanks for reminding us of the 0dp trick – OzzyTheGiant Jun 29 '19 at 04:28
7

It´s simple You set the minWidth or minHeight, depends on what you are looking for, horizontal or vertical. And for the other object(the one that you want to fill the remaining space) you set a weight of 1 (set the width to wrap it´s content), So it will fill the rest of area.

<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>
Daniel
  • 2,780
  • 23
  • 21
6

you can use high layout_weight attribute. Below you can see a layout where ListView takes all free space with buttons at bottom:

<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>
Shankar
  • 2,890
  • 3
  • 25
  • 40
thinker
  • 221
  • 3
  • 8
5

You should avoid nesting 2 relative layout since relative layout always make 2 pass for drawing (against 1 for any other type of layout). It becomes exponential when you nest them. You should use linear layout with width=0 and weight=1 on the element you want to fill the space left. This answer is better for performance and the practices. Remember: use relative layout ONLY when you don't have other choice.

<?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>
Livio
  • 700
  • 6
  • 9
3

For those having the same glitch with <LinearLayout...> as I did:

It is important to specify android:layout_width="fill_parent", it will not work with wrap_content.

OTOH, you may omit android:layout_weight = "0", it is not required.

My code is basically the same as the code in https://stackoverflow.com/a/25781167/755804 (by Vivek Pandey)

Community
  • 1
  • 1
18446744073709551615
  • 16,368
  • 4
  • 94
  • 127
1

When using a relative layout, you can make a view stretch by anchoring it to both of the views it's supposed to stretch toward. Although the specified height will be disregarded, Android still requires a height attribute, which is why I wrote "0dp". Example:

<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

You can use set the layout_width or layout_width to 0dp (By the orientation you want to fill remaining space). Then use the layout_weight to make it fill remaining space.

taynguyen
  • 2,961
  • 1
  • 26
  • 26
0

use a Relativelayout to wrap LinearLayout

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:round="http://schemas.android.com/apk/res-auto"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:orientation="vertical">
    <Button
        android:layout_width = "wrap_content"
        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 = "wrap_content"
        android:layout_height = "wrap_content"
        android:text="&gt;"/>

</LinearLayout>

</RelativeLayout>`
john liao
  • 247
  • 2
  • 3
  • 11
0

i found

 <TextView
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginEnd="10dp"
        android:fontFamily="casual"
        android:text="(By Zeus B0t)"
     ``   android:textSize="10sp"
        android:gravity="bottom"
        android:textStyle="italic" />