Вот мой код макета;
<?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>
То, как это выглядит, слева, и то, на что я хочу, чтобы это выглядело, справа.
Макет Android - фактический (слева) и Желаемый (справа)! Очевидный ответ - установить TextView на fill_parent по высоте, но это не оставляет места для кнопки или поля ввода.
По сути, проблема в том, что я хочу, чтобы кнопка отправки и текстовая запись были фиксированной высотой внизу, а текстовое представление заполняло остальную часть пространства. Точно так же в горизонтальном линейном макете я хочу, чтобы кнопка отправки обернула его содержимое, а текстовая запись заполнила оставшуюся часть пространства.
Если первый элемент в линейном макете задан fill_parent, он делает именно это, не оставляя места для других предметов. Как получить элемент, который первым в линейном макете заполняет все пространство, кроме минимума, требуемого остальными элементами в макете?
< час / >
Относительные макеты были действительно ответом:
<?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>
Современный способ сделать это - иметь ConstraintLayout и ограничивать нижнюю часть вида нижней частью ConstraintLayout приложением : layout_constraintBottom_toBottomOf = "parent"
В приведенном ниже примере создается FloatingActionButton, который будет выровнен по концу и нижней части экрана.
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>
Для справки, я сохраню свой старый ответ.
До введения ConstraintLayout ответом был относительный макет.
Если у вас есть относительный макет, который заполняет весь экран, вы сможете использовать android: layout_alignParentBottom
, чтобы переместить кнопку в нижнюю часть экрана.
Если ваши представления внизу не отображаются в относительном макете, то, возможно, макет выше занимает все пространство. В этом случае вы можете поместить представление, которое должно быть внизу, сначала в файл макета и расположить остальную часть макета над представлениями с помощью android: layout_above
. Это позволяет нижнему виду занимать столько места, сколько ему нужно, а остальная часть макета может заполнить весь остальной экран.
В 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>
Вы можете сохранить свой первоначальный линейный макет, вложив относительный макет в линейный макет:
<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>
Ответ выше (Януш) совершенно правильный, но я лично не чувствую себя на 100% комфортно с RelativeLayouts, поэтому я предпочитаю представить «наполнитель», пустой TextView, вот так:
<!-- filler -->
<TextView android:layout_height="0dip"
android:layout_width="fill_parent"
android:layout_weight="1" />
перед элементом, который должен быть в нижней части экрана.
Вы также можете сделать это с помощью LinearLayout или ScrollView. Иногда это легче реализовать, чем RelativeLayout. Единственное, что вам нужно сделать, это добавить следующее представление перед представлениями, которые вы хотите выровнять по нижней части экрана:
<View
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" />
Это создает пустой вид, заполняя пустое пространство и перемещая следующие виды в нижнюю часть экрана.
Это тоже работает.
<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>
гравитация = «внизу» для перемещения элементов LinearLayout в дно!
ConstraintLayout
в корневом макетеИ установите app: layout_constraintBottom_toBottomOf = "parent"
, чтобы разместить макет в нижней части экрана:
<LinearLayout
android:id="@+id/LinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent">
</LinearLayout>
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>
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>
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>
Следуя элегантному решению Timores, я обнаружил, что следующее создает вертикальное заполнение в вертикальном LinearLayout и горизонтальное заполнение в горизонтальном LinearLayout:
<Space
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" />
Вам даже не нужно вставлять второй «относительный» макет в первый. Просто используйте android: layout_alignParentBottom = "true"
в Button и EditText .
Если вы не хотите вносить много изменений, вы можете просто поставить:
android:layout_weight="1"
для TextView, имеющего идентификатор как @ + id / TextView
, т.е
<TextView android:text="@string/welcome"
android:id="@+id/TextView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
</TextView>
Создание header и footer , вот пример:
<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>
Используйте приведенный ниже код. Выровняйте кнопку до ягодиц. Работает.
<?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>
Для такого случая всегда используйте 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>
Если у вас есть иерархия, как это:
<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>
Вы можете просто указать свой верхний дочерний вид (TextView @ + id / TextView ) атрибут:
android: layout_weight = "1"
.
Это заставит все остальные элементы под ним до дна.
Это также можно сделать с помощью линейного макета.
Просто укажите высоту = 0dp и вес = 1 к макету выше и ту, которую вы хотите внизу. Просто напишите рост = оберните содержание и не вес.
Он предоставляет содержимое обтекания макета (тот, который содержит ваш текст и кнопку редактирования), а затем тот, который имеет вес, занимает остальную часть макета.
Я обнаружил это случайно.
Я использовал решение, опубликованное Янушем, но я добавил в последний вид, так как верхней частью моего макета был ScrollView.
ScrollView будет частично скрыт, поскольку растет вместе с контентом. Использование android: paddingBottom
в последнем представлении помогает показать весь контент в ScrollView.