Как сделать макет с помощью View заполнить оставшееся пространство?

189

Я проектирую пользовательский интерфейс своего приложения. Мне нужен макет выглядит так:

Пример желаемого макета

(<и> - кнопки). Проблема в том, что я не знаю, как убедиться, что TextView заполнит оставшееся пространство, две кнопки имеют фиксированный размер.

Если я использую fill_parent для просмотра текста, вторая кнопка (>) не может быть отображена.

Как я могу создать макет, который выглядит как изображение?

Люк Во
источник
что вы используете в качестве корневого макета?
woodshy
1
@woodshy Любой макет в порядке, это не имеет значения.
Люк Во

Ответы:

213

Ответ от woodshy работал для меня, и это проще, чем ответ Унгуряну Ливиу, поскольку он не использует 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>
Вивек Пандей
источник
Есть такие вещи, как alignLeftи alignParentLeft, и т. Д., Которые никогда не могут быть достигнуты LinearLayout.
IcyFlame
Я не совсем понимаю, как это возможно, но это действительно крутой трюк, чтобы избежать RelativeLayout
a.dibacco
2
Как это может быть принятым ответом? Нет изображения, это только часть решения. По крайней мере, это лучше, чем старый топ-проголосовавший ответ с Relative Layout (я объяснил почему в своем ответе)
Livio
гениальное решение
Мохаммад Эльсайед
93

В случае если <TEXT VIEW> помещен в LinearLayout, установите для свойства Layout_weight для <и> значение 0 и 1 для TextView.
В случае RelativeLayout выровняйте <и> по левому и правому краям и установите для свойства «Макет слева от» и «Макет справа от» TextView идентификаторы <и>

woodshy
источник
Кому-нибудь еще нужен образец?
woodshy
Как добавить изображения в этот макет, чтобы заполнить весь вид
Tushar Pandey
как вы добавите изображение в относительный макет, чтобы заполнить весь вид
Тушар Пандей
4
@woodshy да, образец все равно будет полезен
Фрэнк Швитерман,
Посмотрите на ответ Вивека Пандея для примера
MyDogTom
71

Если вы используете 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 не заполняет все пространство, не для >кнопки?
Люк Во
2
Почему есть два вложенных относительных макета? Корневого должно быть достаточно. Затем все, что вам нужно сделать, это убедиться, что все дочерние элементы относительной компоновки нижнего уровня равны alignParentBottom = "true"
Noel
@ Ноэль Ты прав. Я выбираю 2 макета, потому что так я использую: в моих приложениях может случиться так, что мне понадобится изменить видимость нескольких видов, и будет проще поместить их все в макет и изменить видимость только для этого макета. , Мой пример не идеален, но он работает, и это может быть полезно для кого-то.
Унгуряну Ливиу
1
@WN Это тоже странно для меня :) Я думаю, что текстовое представление не использует все пространство, потому что правая кнопка имеет фиксированную ширину. Если вы измените android: layout_width = "80dp" на android: layout_width = "wrap_content" для правой кнопки, это будет работать.
Унгуряну Ливиу
2
Этот ответ действительно плохой! Вам следует избегать вложения 2 относительного расположения, так как относительное расположение всегда делает 2 прохода для рисования (против 1 для любого другого типа расположения). Это становится экспоненциальным, когда вы их вкладываете. Вы должны использовать линейный макет с шириной = 0 и весом = 1 для элемента, который вы хотите заполнить оставшееся пространство. Помните: используйте относительное расположение ТОЛЬКО тогда, когда у вас нет другого выбора. stackoverflow.com/questions/4069037/…
Ливио
30

Используя 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и позволяет ему определить свой собственный размер.

Том Ховард
источник
4
Просто начав использовать ConstraintLayout, здорово знать, что ширина и высота могут определяться ограничениями при установке их в «0», спасибо за это :)
MQoder
Важно быть осторожным относительно направления стрелки каждого ограничения. Убедитесь, что TextViewесть левые и правые ограничения. Значение TextViewне растягивается, если первое Buttonимеет правое ограничение для, TextViewа последнее Buttonимеет левое ограничение для TextView.
Мануэль
намного лучше! повышает производительность, не имея вложенных макетов. Спасибо за то, что напомнили нам о трюке 0dp
OzzyTheGiant
7

Это просто Вы устанавливаете 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>
Даниил
источник
4

Вы можете использовать высокий атрибут 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>
мыслитель
источник
3

Для тех, у кого такой же глюк, <LinearLayout...>как и у меня:

Важно указать android:layout_width="fill_parent", он не будет работать wrap_content.

OTOH, вы можете опустить android:layout_weight = "0", это не требуется.

Мой код в основном совпадает с кодом в https://stackoverflow.com/a/25781167/755804 (автор Vivek Pandey)

18446744073709551615
источник
3

Вам следует избегать вложения 2 относительного расположения, так как относительное расположение всегда делает 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>
Ливио
источник
0

Вы можете использовать установить layout_widthили layout_widthв 0dp(По ориентации вы хотите заполнить оставшееся пространство). Затем используйте, layout_weightчтобы заполнить оставшееся пространство.

taynguyen
источник
0

используйте Relativelayout для переноса 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>`
Джон Ляо
источник
0

я нашел

 <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" />
Зевс B0t
источник
0

При использовании относительного макета вы можете растянуть вид, привязав его к обоим видам, к которым он должен быть растянут. Хотя указанная высота не будет учитываться, 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"/>
ФК Джулиано
источник