Как выровнять виды внизу экрана?

542

Здесь мой код макета;

<?xml version="1.0" encoding="utf-8"?>
<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:text="@string/welcome" 
        android:id="@+id/TextView" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content">
    </TextView>

    <LinearLayout android:id="@+id/LinearLayout" 
        android:orientation="horizontal"
        android:layout_width="wrap_content" 
        android:layout_height="wrap_content" 
        android:gravity="bottom">

            <EditText android:id="@+id/EditText" 
                android:layout_width="fill_parent" 
                android:layout_height="wrap_content">
            </EditText>

            <Button android:text="@string/label_submit_button" 
                android:id="@+id/Button" 
                android:layout_width="wrap_content" 
                android:layout_height="wrap_content">
            </Button>

    </LinearLayout>

</LinearLayout>

Похоже, что это слева, и я хочу, чтобы он выглядел справа.

Изображение 183

Очевидным ответом является установка TextView на fill_parent по высоте, но это не оставляет места для кнопки или поля ввода. По сути, проблема заключается в том, что я хочу, чтобы кнопка отправки и текстовая запись были фиксированной высотой внизу и текстовым видом, чтобы заполнить остальную часть пространства, аналогично горизонтальной линейной компоновке. Я хочу, чтобы кнопка отправки обернула ее содержимое и для ввода текста, чтобы заполнить остальную часть пространства.

Если первый элемент в линейной компоновке сказал fill_parent, он делает именно это, не оставляя места для других предметов, как мне получить элемент, который первым в линейном макете, чтобы заполнить все пространство, кроме минимума, необходимого для остальные элементы в макете?

EDIT:

Относительные макеты действительно были ответом - Спасибо!

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent">

    <TextView 
        android:text="@string/welcome" 
        android:id="@+id/TextView"
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true">
    </TextView>

    <RelativeLayout 
        android:id="@+id/InnerRelativeLayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

        <Button 
            android:text="@string/label_submit_button" 
            android:id="@+id/Button"
            android:layout_alignParentRight="true" 
            android:layout_width="wrap_content"
            android:layout_height="wrap_content">
        </Button>

        <EditText 
            android:id="@+id/EditText" 
            android:layout_width="fill_parent"
            android:layout_toLeftOf="@id/Button"
            android:layout_height="wrap_content">
        </EditText>

    </RelativeLayout>

</RelativeLayout>
  • 6
    Как вы создали эти скриншоты?
  • 7
    @oneself Paint;) Я использую скин на эмуляторе, хотя любезно предоставлено Tea Vui Huang teavuihuang.com/android
Показать ещё 2 комментария
Теги:
user-interface
android-layout

18 ответов

421
Лучший ответ

Я думаю, вы должны попробовать относительный макет.
Если у вас есть относительный макет, заполняющий весь экран, вы можете использовать android:layout_alignParentBottom, чтобы переместить кнопку в нижней части экрана.

Если ваши представления внизу не показаны в относительном макете, то, возможно, макет над ним занимает все пространство. В этом случае вы можете поместить представление, которое должно быть внизу, сначала в вашем файле макета, и расположите остальную часть макета над представлениями с помощью android:layout_above. Это позволяет нижнему виду занять столько места, сколько потребуется, а остальная часть макета может заполнить всю оставшуюся часть экрана.

  • 4
    К вашему сведению: это не будет работать внутри ScrollView. Это проблема, с которой я сталкиваюсь сейчас. См. Stackoverflow.com/questions/3126347/…
  • 6
    Это верно, ScrollViews и Relative Layouts не очень хорошо сочетаются. Если вам нужно много контента, чтобы отобразить все на одной странице, просто используйте линейный макет и поместите в нижний вид в последнюю очередь. Если вы хотите, чтобы представление отображалось последним в представлении прокрутки на небольших экранах и в нижней части страницы на более крупных телефонах, рассмотрите возможность использования различных файлов макетов и использования классификаторов ресурсов, чтобы устройство могло выбрать правильный файл макета.
Показать ещё 4 комментария
121

В ScrollView это не работает, так как RelativeLayout будет перекрывать все, что находится в ScrollView в нижней части страницы.

Я исправил его с помощью динамического растяжения FrameLayout:

<ScrollView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent" 
    android:layout_width="match_parent"
    android:fillViewport="true">
    <LinearLayout 
        android:id="@+id/LinearLayout01"
        android:layout_width="match_parent" 
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical">

                <!-- content goes here -->

                <!-- stretching frame layout, using layout_weight -->
        <FrameLayout
            android:layout_width="match_parent" 
            android:layout_height="0dp"
            android:layout_weight="1">
        </FrameLayout>

                <!-- content fixated to the bottom of the screen -->
        <LinearLayout 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                                   <!-- your bottom content -->
        </LinearLayout>
    </LinearLayout>
</ScrollView>
  • 1
    это здорово - также, это «минимально инвазивный» и более интуитивный, чем подход RelativeLayout. Я бы дал больше одного голоса, если бы мог!
  • 4
    Я использую ваше решение в своем приложении, но в моем случае я хочу, чтобы при появлении клавиатуры кнопки оставались в нижней части экрана (за клавиатурой). Thaks.
Показать ещё 3 комментария
57

Вы можете сохранить свой первоначальный линейный макет, вставив относительный макет в линейный макет:

<LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <TextView android:text="welcome" 
        android:id="@+id/TextView" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content">
    </TextView>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <Button android:text="submit" 
            android:id="@+id/Button" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_alignParentRight="true">
        </Button>
        <EditText android:id="@+id/EditText" 
            android:layout_width="match_parent" 
            android:layout_height="wrap_content"
            android:layout_toLeftOf="@id/Button"
            android:layout_alignParentBottom="true">
        </EditText>
    </RelativeLayout>
</LinearLayout>
  • 2
    Это грязный подход, поскольку он не очень модульный. Вы не должны иметь перекрывающихся макетов. Этот дизайн не будет работать, как только вы захотите изменить фон RelativeLayout или захотите увеличить любой из видов или добавить их.
33

Ответ выше (по Janusz) вполне корректен, но я лично не чувствую себя на 100% совместимым с RelativeLayouts, поэтому предпочитаю вводить "filler", пустой TextView, например:

<!-- filler -->
<TextView android:layout_height="0dip" 
          android:layout_width="fill_parent"
          android:layout_weight="1" />

перед элементом, который должен находиться в нижней части экрана.

  • 0
    Это расширится до оси X или Y. Задание 0dip для высоты сделает текстовое представление без какой-либо высоты? или будет расширяться настолько, насколько это возможно, просто как на оси х?
  • 0
    Это расширяется по вертикали, потому что высота (вертикальная ось) установлена в 0, а вес в 1 (при условии, что другие элементы имеют нулевой вес).
Показать ещё 2 комментария
24

Это также работает.

<LinearLayout 
    android:id="@+id/linearLayout4"
    android:layout_width="wrap_content"
    android:layout_height="fill_parent"
    android:layout_below="@+id/linearLayout3"
    android:layout_centerHorizontal="true"
    android:orientation="horizontal" 
    android:gravity="bottom"
    android:layout_alignParentBottom="true"
    android:layout_marginTop="20dp"
>

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 

    />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Button" 


    />

</LinearLayout>

Изображение 3068

  • 12
    android: layout_alignParentBottom = "true" не имеет никакого эффекта, если только LinearLayout не вложен в RelativeLayout.
22

Вы можете сделать это с помощью LinearLayout или ScrollView. Иногда легче реализовать, чем RelativeLayout. Единственное, что вам нужно сделать, это добавить следующий вид до Представления, которые вы хотите выровнять в нижней части экрана:

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

Это создает пустой вид, заполняя пустое пространство и нажимая следующие представления в нижней части экрана.

15

Следуя элегантному решению Timores, я обнаружил, что следующее создает вертикальное заполнение вертикального LinearLayout и горизонтальное заполнение горизонтального LinearLayout:

<Space
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_weight="1" />
  • 1
    Решение @ stevehs17 не работает во фрагменте
  • 0
    @sepehr Должен быть другой фактор в случае, если вы обнаружили, что мое решение не работает. Я только что попробовал свое решение в макете фрагмента, и оно работает там же.
Показать ещё 1 комментарий
14

Вам даже не нужно вставлять второй макет relative внутри первого. Просто используйте android:layout_alignParentBottom="true" в Button и EditText.

  • 0
    Просто обратите внимание, что хотя это работает с Button и EditText, если вы попытаетесь выровнять TableLayout таким образом, он не будет работать. Вы должны будете вложить его в другой RelativeLayout.
9

Если вы не хотите делать много изменений, вы можете просто поставить:

android:layout_weight="1"

для TextView с ID как @+id/TextView i.e

<TextView android:text="@string/welcome" 
    android:id="@+id/TextView" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    android:layout_weight="1">
</TextView>
  • 0
    Или добавьте окружающий LinearLayout с android: layout_weight = "1" - это также хорошо работает внутри ScrollView!
6

Создавая как HEADER, так и FOOTER, вот пример

[Layout XML]

<RelativeLayout
    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"
    android:background="@color/backgroundcolor"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:background="#FF0000">
    </RelativeLayout>

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:layout_alignParentBottom="true"
        android:background="#FFFF00">
    </RelativeLayout>

</RelativeLayout>

[Снимок экрана]

Изображение 3069

Надеюсь, это полезно. Спасибо!!

4

используйте нижнюю кнопку выравнивания кода, чтобы уменьшить ее рабочие

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

    <Button
        android:id="@+id/btn_back"
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:text="Back" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="0.97"
        android:gravity="center"
        android:text="Payment Page" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <EditText
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:layout_weight="1"/>

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" 
            android:text="Submit"/>
    </LinearLayout>

</LinearLayout>
2

Если у вас есть такая иерархия:

<ScrollView> 
  |-- <RelativeLayout> 
    |-- <LinearLayout>

Сначала примените android:fillViewport="true" к ScrollView, а затем примените android:layout_alignParentBottom="true" к LinearLayout.

Это сработало для меня отлично.

<ScrollView
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:scrollbars="none"
    android:fillViewport="true">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:id="@+id/linearLayoutHorizontal"
            android:layout_alignParentBottom="true">
        </LinearLayout>
    </RelativeLayout>
</ScrollView>
2

Используйте android:layout_alignParentBottom="true" в <RelativeLayout>.

Это определенно поможет.

  • 1
    Это предполагает, что пользователь хочет использовать RelativeLayout.
1

1.Use ConstraintLayout в корневом макете

И установите app:layout_constraintBottom_toBottomOf="parent", чтобы Layout в нижней части экрана

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>

2.Используйте FrameLayout в корневом макете

Просто установите android:layout_gravity="bottom" в вашем макете

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

3.Используйте LinearLayout в корневом макете (android:orientation="vertical")

(1) Установите макет android:layout_weight="1" в верхней части макета

<TextView
    android:id="@+id/TextView"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1"
    android:text="welcome" />

(2) Установите дочерний элемент LinearLayout для android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="bottom"

Основной атрибут ndroid:gravity="bottom", пусть дочерний вид в нижней части макета.

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="bottom"
    android:orientation="horizontal">
</LinearLayout>

4.Use RelativeLayout в корневом макете

И установите android:layout_alignParentBottom="true", чтобы макет в нижней части экрана

<LinearLayout
    android:id="@+id/LinearLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:orientation="horizontal">
</LinearLayout>

OUTPUT

Изображение 3070

1

Вы можете просто дать вашему верхнему дочернему виду (TextView @+ id/TextView) атрибут:   android:layout_weight="1".

Это приведет к тому, что все остальные элементы будут внизу внизу.

0

Для такого случая всегда используйте RelativeLayouts. LinearLayout не предназначен для такого использования.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/db1_root"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:orientation="vertical" >

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!-- Place your layout here -->

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_gravity="bottom"
    android:orientation="horizontal"
    android:paddingLeft="20dp"
    android:paddingRight="20dp" >

    <Button
        android:id="@+id/setup_macroSavebtn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Save" />

    <Button
        android:id="@+id/setup_macroCancelbtn"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="Cancel" />

    </LinearLayout>

</RelativeLayout>
0

Это можно сделать и с линейной компоновкой Просто поставьте Height = 0dp и weight = 1 в макет выше, а тот, который вы хотите в нижней части, просто напишите height = wrap content и no weight. То, что он делает, это предоставление содержимого обложки для макета (тот, который содержит текст редактирования и кнопку), а затем тот, который имеет вес, занимает остальную часть макета. Я обнаружил это случайно.

0

Я использовал решение Janusz, но добавил добавление к последнему представлению, так как верхняя часть моего макета была ScrollView. ScrollView будет частично скрыт, поскольку он растет с контентом. Использование android: paddingBottom в последнем представлении помогает показать все содержимое в ScrollView.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню