6 лет назад

Android. Обзор RelativeLayout


С компоновкой LinearLayout разобрались, а теперь приступим к изучению другой популярной компоновки RelativeLayout.

В этой компоновке элементы в контейнере выстраиваются относительно либо контейнера, либо других элементов в этом контейнере.

Рассмотрим XML атрибуты и JAVA константы для выстраивания относительных связей.


Расположение относительно родительского элемента

У атрибута булево значение – true (использовать), false (не использовать – это значение по умолчанию)

Таблица №1
XML атрибут  JAVA константа  Действие
android:layout_centerInParent RelativeLayout.CENTER_IN_PARENT Элемент располагается в центре родительского элемента по горизонтали и вертикали
android:layout_centerHorizontal RelativeLayout.CENTER_HORIZONTAL Элемент располагается в центре родительского элемента по горизонтали
android:layout_centerVertical RelativeLayout.CENTER_VERTICAL Элемент располагается в центре родительского элемента по вертикали
android:layout_alignParentBottom RelativeLayout.ALIGN_PARENT_BOTTOM Нижняя граница элемента располагается на нижней границе контейнера RelativeLayout
android:layout_alignParentLeft RelativeLayout.ALIGN_PARENT_LEFT Левая граница элемента располагается на левой границе  контейнера RelativeLayout
android:layout_alignParentRight RelativeLayout.ALIGN_PARENT_RIGHT Правая граница элемента располагается на правой границе контейнера RelativeLayout
android:layout_alignParentTop RelativeLayout.ALIGN_PARENT_TOP Верхняя граница элемента располагается на верхней границе контейнера RelativLayout
android:layout_alignWithParentIfMissing Если указанный элемент (см. таблицу ниже) не найден, то для выравнивания будет использоваться родительский контейнер компоновки

Расположение относительно других элементов

Значением атрибута является id другого элемента

  • @id/name_id – если id или элемент с этим id уже определен в макете
  • @+id/name_id – если id не определён. Плюс указывает на создание id.
  • R.id.name_id – обращение к id из JAVA
Таблица №2
XML атрибут JAVA константа Действие
android:layout_above RelativeLayout.ABOVE Расположить элемент над указанным ID элемента
android:layout_below RelativeLayout.BELOW Расположить элемент под указанным ID элемента
android:layout_toLeftOf RelativeLayout.LEFT_OF Расположить элемент слева от указанного ID элемента
android:layout_toRightOf RelativeLayout.RIGHT_OF Расположить элемент справа от указанного ID элемента
android:layout_alignBottom RelativeLayout.ALIGN_BOTTOM Нижняя граница элемента выравнивается по нижней границе другого элемента
android:layout_alignLeft RelativeLayout.ALIGN_LEFT Левая граница элемента выравнивается по левой границе другого элемента
android:layout_alignRight RelativeLayout.ALIGN_RIGHT Правая граница элемента выравнивается по правой границе другого элемента
android:layout_alignTop RelativeLayout.ALIGN_TOP Верхняя граница элемента выравнивается по верхней границе другого элемента
android:layout_alignBaseline RelativeLayout.ALIGN_BASELINE Базовая линия элемента выравнивается по базовой линии другого элемента

Приступим к примерам

Рассмотрим как можно расположить элементы относительно других элементов.
Для начала картинка того, что у нас получится:

пример RelativeLayoutпример RelativeLayout

Пример 1
<?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">
    <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button1"
            android:text="Button 1"/>
    <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button2"
            android:layout_toRightOf="@id/button1"
            android:text="Button 2 (layout_toRightOf)"/>
    <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button3"
            android:layout_below="@id/button1"
            android:text="Button 3 (layout_below)"/>
    <Button android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button4"
            android:layout_below="@id/button1"
            android:layout_toRightOf="@id/button3"
            android:text="Button 4 (layout_below and layout_toRightOf)"/>
</RelativeLayout>
Разбираем код.

Для начала мы создаём кнопку Button 1 и присваиваем ей id button1.

Кнопку Button 2 мы хотим разместить правее кнопки Button 1 и для этого смотрим в таблицу №2 (Расположить элемент справа) и указываем у кнопки Button 2 данный атрибут и id 1-ой кнопки.
android:layout_toRightOf="@id/button1"
Теперь вторая кнопка у нас справа.

Третью кнопку Button 3 мы хотим разместить под кнопкой Button 1. Опять смотрим в таблички. Ага, расположить элемент под указанным id - это атрибут layout_below
android:layout_below="@id/button1"
  4-ая кнопка будет располагаться правее кнопки Button 3 и ниже первой кнопки.
android:layout_below="@id/button1"
android:layout_toRightOf="@id/button3"

Создадим макет поинтереснее, например, форму авторизации.

пример RelativeLayout портретная ориентацияпример RelativeLayout landskape ориентация

Пример 2
<?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"
                android:background="#eee"
        >
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerHorizontal="true"
              android:layout_marginTop="5dp"
              android:textSize="17sp"
              android:text="DevPad.RU"/>
    <RelativeLayout android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:background="#ccc"
                    android:paddingTop="10dp"
            >
        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_centerHorizontal="true"
                  android:id="@+id/title"
                  android:layout_marginBottom="20dp"
                  android:textStyle="bold"
                  android:text="Введите Ваши данные"/>
        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginLeft="20dp"
                  android:layout_marginRight="30dp"
                  android:id="@+id/text_login"
                  android:layout_below="@id/title"
                  android:text="Login:"/>
        <EditText android:layout_width="fill_parent"
                  android:layout_height="30dp"
                  android:layout_marginRight="20dp"
                  android:layout_below="@id/title"
                  android:layout_toRightOf="@id/text_login"/>

        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:layout_marginTop="20dp"
                  android:layout_marginLeft="20dp"
                  android:layout_marginRight="5dp"
                  android:id="@+id/text_password"
                  android:layout_below="@id/text_login"
                  android:text="Password:"/>
        <EditText android:layout_width="fill_parent"
                  android:layout_height="30dp"
                  android:layout_marginRight="20dp"
                  android:layout_marginTop="20dp"
                  android:layout_below="@id/text_login"
                  android:layout_toRightOf="@id/text_password"/>
        <Button android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Войти"
                android:layout_margin="20dp"
                android:id="@+id/btn_enter"
                android:layout_centerHorizontal="true"
                android:layout_below="@id/text_password"/>
    </RelativeLayout>
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentBottom="true"
              android:layout_centerHorizontal="true"
              android:textSize="15sp"
              android:textColor="#00f"
              android:id="@+id/reg_link"
              android:text="Зарегистрироваться"/>
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerHorizontal="true"
              android:layout_above="@id/reg_link"
              android:textSize="17sp"
              android:text="Нет аккаунта?"/>
</RelativeLayout>
Разбираемся.
Вначале мы заливаем экран светло серым фоном, а затем добавляем заголовок к нашей форме:
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:textSize="17sp"
android:text="DevPad.RU"/>
Обратите внимание на android:layout_centerHorizontal="true" – это обозначает, что нужно выровнять текст по центру горизонтальной направленности. В разметке LinearLayout для этого мы бы использовали android:layout_gravity="center_horizontal".

Далее мы создадим ещё один контейнер разметки для того, чтобы выровнять его по центру экрана. Для этого мы воспользуемся атрибутом android:layout_centerInParent. Чтобы визуально выделить этот фрагмент, мы зададим ему фоновый серый цвет.
<RelativeLayout android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#ccc"
android:paddingTop="10dp"
>
Теперь по уже знакомому сюжету мы добавляем текст по середине экрана в горизонтальном направлении и присваиваем ему id равное title. Под ним с помощью android:layout_below="@id/title" располагаем текст «Login:» и устанавливаем ему id android:id="@+id/text_login". Правее текста располагаем поле текстового ввода. Для это используем android:layout_below="@id/title" иandroid:layout_below="@id/title" и  android:layout_toRightOf="@id/text_login". По аналогии делаем тоже самое с полем ввода для пароля. Под вводом пароля по середине экрана разместим кнопку входа. Для этого зададим ей уже знакомый атрибут android:layout_centerHorizontal="true" и укажем, что кнопка должна быть после ввода пароля android:layout_below="@id/text_password". Всё, вложенный контейнер RelativeLayout закрываем.
Нам остаётся сейчас разместить внизу экрана ссылку на регистрацию. Смотрим в таблицы и находим, как можно расположить элемент относительно контейнера в нижней границе.
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:textSize="15sp"
android:textColor="#00f"
android:id="@+id/reg_link"
android:text="Зарегистрироваться"/>
В итоге имеем текст написанный синим цветом внизу экрана по середине. Его можно сделать  кликабельным, но это не входит в тему этого поста.
Хорошо бы ещё что-то написать поверх ссылки зарегистрироваться. Для этого есть атрибут, позволяющий расположить элемент над указанным элементом – layout_above.
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_above="@id/reg_link"
android:textSize="17sp"
android:text="Нет аккаунта?"/>
Вот таким нехитрым примером мы и разобрали некоторые атрибуты контейнера.


А сейчас мы рассмотрим расположение элементов относительно родительского элемента (см. таблица 1).
Расположим элементы по всем краям контейнера.

пример работы с контейнером RelativeLayout портретная ориентацияпример работы с контейнером RelativeLayout ландшафтная ориентация

Пример 3
<?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:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentLeft="true"
              android:text="Text 1"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentTop="true"
              android:layout_centerHorizontal="true"
              android:text="Text 2"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentTop="true"
              android:layout_alignParentRight="true"
              android:text="Text 3"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentLeft="true"
              android:layout_centerVertical="true"
              android:text="Text 4"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerInParent="true"
              android:text="Text 5"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentRight="true"
              android:layout_centerVertical="true"
              android:text="Text 6"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentBottom="true"
              android:text="Text 7"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerHorizontal="true"
              android:layout_alignParentBottom="true"
              android:text="Text 8"
            />
    <TextView android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_alignParentBottom="true"
              android:layout_alignParentRight="true"
              android:text="Text 9"
            />
</RelativeLayout>
Отдельных пояснений по примеру не будет. Если смотреть на пример, на результат в виде скриншота и на таблицу с описание атрибутов, то всё должно стать на свои места.

В посте «Всё о LinearLayout – 1» мы рассматривали один из примеров с макетом сообщения.
Давайте теперь сделаем тоже самое, но уже используя разметку RelativeLayout.

Пример Android компоновки RelativeLayoutПример Android компоновки RelativeLayout

Пример 4
<?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"
        >
    <RelativeLayout android:layout_width="fill_parent"
                    android:layout_height="wrap_content"
                    android:paddingTop="5dp"
                    android:paddingBottom="5dp"
                    android:background="#ddd"
                    android:id="@+id/list"
            >
        <ImageView android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_gravity="center"
                   android:layout_marginRight="10dp"
                   android:layout_marginLeft="5dp"
                   android:scaleType="fitCenter"
                   android:src="@drawable/anonym"
                   android:id="@+id/contact_image"
                />
        <TextView android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="Аноним"
                  android:textSize="20sp"
                  android:textStyle="bold"
                  android:layout_toRightOf="@id/contact_image"
                  android:id="@+id/contact_name"
                />
        <LinearLayout android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:layout_toRightOf="@id/contact_image"
                      android:layout_below="@id/contact_name"
                >
            <TextView android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:text="Пропущенных вызовов от абонента - 1, время 20:48 09/12"
                      android:layout_weight="0.9"
                      android:textSize="13sp"
                      android:maxLines="2"/>
            <TextView android:layout_width="fill_parent"
                      android:layout_height="wrap_content"
                      android:layout_weight="1.9"
                      android:layout_gravity="bottom"
                      android:gravity="right"
                      android:paddingRight="5dp"
                      android:text="11/11/12"
                      android:textSize="12sp"
                      android:textColor="#00f"
                    />
        </LinearLayout>
    </RelativeLayout>
    <Button android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Удалить всё"
            android:gravity="center"
            android:layout_below="@id/list"
            />
</RelativeLayout>
В этом коде, мы поместили в корневой контейнер, контейнер RelativeLayout и задали ему серый фоновый цвет.
Внутрь контейнера мы поместили изображение контакта. Правее изображения (android:layout_toRightOf="@id/contact_image"), мы поместили имя контакта. Под именем контакта и правее изображения контакта, мы поместили другой контейнер компоновки LinearLayout.
android:layout_height="wrap_content"
android:layout_toRightOf="@id/contact_image"
android:layout_below="@id/contact_name"
Этот контейнер хорош, когда нужно пропорционально распределить элементы внутри при помощи android:layout_weight. В контейнере RelativeLayout к сожалению нет данного атрибута. Внутрь контейнера добавляем 2 текстовых элемента.

Обратите внимание, что внутри этого контейнера LinearLayout, уже не работают атрибуты из RelativeLayout и вам необходимо использовать для вложенных элементов только разрешённые атрибуты его "родителя"
Ну и на последок добавим под сообщением кнопку "Удалить всё". Для этого разместим её после вложенного контейнера RelativeLayout и укажем на его id.
android:layout_below="@id/list"

Программное создание компоновки на JAVA

Создание компоновки мало чем отличается от варианта с LinearLayout.
Однако, чтобы задать элементам относительное расположение, нужно воспользоваться вложенным классом RelativeLayout.LayoutParams и его методом addRule. Первым параметром указывается константа из таблиц, находящихся вначале поста и если нужно указать id элемента, то его добавляют вторым параметром.

Рассмотрим пример:
Button button1 = new Button(this);
RelativeLayout.LayoutParams buttonParam1 = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT, 
        ViewGroup.LayoutParams.WRAP_CONTENT
);
button1.setText("Button 1");
button1.setId(BUTTON_ID_1);
button1.setLayoutParams(buttonParam1);

Button button2 = new Button(this);
RelativeLayout.LayoutParams buttonParam2 = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT, 
        ViewGroup.LayoutParams.WRAP_CONTENT
);
buttonParam2.addRule(RelativeLayout.BELOW, button1.getId());
buttonParam2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
button2.setText("Button 2");
button2.setLayoutParams(buttonParam2);

RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.FILL_PARENT, 
        ViewGroup.LayoutParams.FILL_PARENT
);
relativeLayout.setLayoutParams(param);

relativeLayout.addView(button1);
relativeLayout.addView(button2);

setContentView(relativeLayout);
В результате у нас получилось следующее:

Android. RelativeLayout programmatically

В начале мы создали 2 кнопки. 2-ой кнопке мы применили правила расположиться после первой кнопки и по правому краю контейнера RelativeLayout.

RelativeLayout.LayoutParams buttonParam2 = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT
);
buttonParam2.addRule(RelativeLayout.BELOW, button1.getId());
buttonParam2.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
После задания параметров у кнопок, мы создаём корневой контейнер RelativeLayout и добавляем в него эти кнопки
RelativeLayout relativeLayout = new RelativeLayout(this);
RelativeLayout.LayoutParams param = new RelativeLayout.LayoutParams(
        ViewGroup.LayoutParams.FILL_PARENT,
        ViewGroup.LayoutParams.FILL_PARENT
);
relativeLayout.setLayoutParams(param);

relativeLayout.addView(button1);
relativeLayout.addView(button2);
После чего отображаем компоновку на экране
setContentView(relativeLayout);

На этом всё. Спасибо за внимание.

Исходники примеров на гитхабе - https://github.com/devpad/Android-RelativeLayout-1
Поделиться ссылкой:

comments powered by Disqus