Изменение activity_user_info, используя RelativeLayout.
В прошлом уроке мы с вами сделали экран отображения данных пользователя, используя контейнер (ViewGroup) LinearLayout. В этом уроке мы создадим этот экран заново, используя RelativeLayout.
В следующих уроках на этом экране будут добавляться ещё дополнительные элементы, поэтому замена контейнера на RelativeLayout сделана не просто для учебных целей.
Исходя из названия, RelativeLayout (рус. относительный макет или если перефразировать – макет с относительным расположением элементов) может располагать элементы относительно друг друга. У его вложенных элементов есть ряд параметров для указания зависимостей относительно остальных элементов или же самого RelativeLayout.
Элементы внутри RelativeLayout имеют свойства отвечающие за их расположение по вертикали и горизонтали. По умолчанию горизонтальное свойство расположения прижато к левому краю RelativeLayout, а вертикальное к верхнему. Получается по умолчанию расположение элементов зависят от верхнего и левого края родительского контейнера RelativeLayout. Часто такое зависящее от чего-то расположение для удобства называют зависимостью. Например, установить для текста зависимость снизу от кнопки и справа от родительского контейнера. Если вы не укажете ни одной зависимости, то все элементы будут располагаться один над одним в верхнем левом углу. Причём элемент, который будет ниже всего в xml файле будет находиться поверх остальных.
Давайте изменим структуру нашего activity_user_info.xml файла. Заменим корневой элемент на RelativeLayout (удалив свойство android:orientation="vertical" потому что оно не применяется к RelativeLayout) и вставим версию нашего layout, когда все элементы лежат на одном уровне (без вложенного контейнера LinearLayout) :
Теперь нам необходимо исправить эту ситуацию. В левом верхнем углу должен остаться user_image_view, а user_name_text_view должен находиться под ним. Для этого применим свойство android:layout_below="@id/user_image_view". Оно делает именно то, что нам надо. У RelativeLayout есть такие же свойства только для других направлений:
android:layout_below – находиться под элементом.
android:layout_above – находиться над элементом.
android:layout_toStartOf – находиться слева(в начале) от элемента.
android:layout_toEndOf – находиться справа (в конце) от элемента
Сейчас нам достаточно добавить зависимость android:layout_below для каждого нижестоящего элемента:
Выглядит уже лучше, но последний элемент(followers_text_view) должен находиться не под following_text_view, а справа от него. Мы хотим, чтобы наш элемент находился снизу от user_location_text_view и справа от following_text_view. Добавим атрибуты android:layout_below="@id/user_location_text_view" и android:layout_toEndOf="@+id/following_text_view" к элементу followers_text_view.
activity_user_info.xml
<RelativeLayout>
<!--Остальные элементы сверху не изменились -->
<TextViewandroid:id="@+id/followers_text_view"android:layout_below="@id/user_location_text_view"android:layout_toEndOf="@+id/following_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:layout_marginTop="5dp"android:text="Читатели"android:textSize="16sp"/>
</RelativeLayout>
После этого видим, что мы получили такой же layout, как в предыдущем уроке:
Какие преимущества от того, что мы используем RelativeLayout? Мы убрали вложенный контейнер LinearLayout. В данном примере это было не критично, но вообще важно помнить, что слишком глубокая вложенность приводит к снижению производительности пользовательского интерфейса. Хорошей практикой является вложенность не больше 10 уровней.
Осталась ещё одна вещь, которую надо помнить, когда используете RelativeLayout. Нельзя объявлять круговые (транзитивные) зависимости. Т.е. если мы зададим кнопке свойство android:layout_toStartOf="@+id/search_edit_text", а к EditText добавим зависимость android:layout_toStartOf="@+id/search_button", то приложение выдаст исключение java.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout. Можете проверить это, если не верите :)
Подведём итоги:
RelativeLayout позволяет элементам указывать зависимости как относительно друг друга, так и относительно сторон самого родительского контейнера RelativeLayout.
Его нужно использовать, когда мы видим не линейную структуру элементов.
RelativeLayout позволяет избавиться от вложенности контейнеров в отличие от LinearLayout
Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для
продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.
Код начала урока:
gitzip
Структура урока:
Видео версия урока
Изменение activity_user_info, используя RelativeLayout.
В прошлом уроке мы с вами сделали экран отображения данных пользователя, используя контейнер (ViewGroup)
LinearLayout
. В этом уроке мы создадим этот экран заново, используяRelativeLayout
.Исходя из названия,
RelativeLayout
(рус. относительный макет или если перефразировать – макет с относительным расположением элементов) может располагать элементы относительно друг друга. У его вложенных элементов есть ряд параметров для указания зависимостей относительно остальных элементов или же самогоRelativeLayout
.Элементы внутри
RelativeLayout
имеют свойства отвечающие за их расположение по вертикали и горизонтали. По умолчанию горизонтальное свойство расположения прижато к левому краюRelativeLayout
, а вертикальное к верхнему. Получается по умолчанию расположение элементов зависят от верхнего и левого края родительского контейнераRelativeLayout
. Часто такое зависящее от чего-то расположение для удобства называют зависимостью. Например, установить для текста зависимость снизу от кнопки и справа от родительского контейнера. Если вы не укажете ни одной зависимости, то все элементы будут располагаться один над одним в верхнем левом углу. Причём элемент, который будет ниже всего вxml
файле будет находиться поверх остальных.Давайте изменим структуру нашего
activity_user_info.xml
файла. Заменим корневой элемент наRelativeLayout
(удалив свойствоandroid:orientation="vertical"
потому что оно не применяется кRelativeLayout
) и вставим версию нашегоlayout
, когда все элементы лежат на одном уровне (без вложенного контейнераLinearLayout
) :activity_user_info.xml
Смотрим, как он выглядит на вкладке
Design
:Теперь нам необходимо исправить эту ситуацию. В левом верхнем углу должен остаться
user_image_view
, аuser_name_text_view
должен находиться под ним. Для этого применим свойствоandroid:layout_below="@id/user_image_view"
. Оно делает именно то, что нам надо. УRelativeLayout
есть такие же свойства только для других направлений:android:layout_below
– находиться под элементом.android:layout_above
– находиться над элементом.android:layout_toStartOf
– находиться слева(в начале) от элемента.android:layout_toEndOf
– находиться справа (в конце) от элементаСейчас нам достаточно добавить зависимость
android:layout_below
для каждого нижестоящего элемента:activity_user_info.xml
В результате видим:
Выглядит уже лучше, но последний элемент(
followers_text_view
) должен находиться не подfollowing_text_view
, а справа от него. Мы хотим, чтобы наш элемент находился снизу отuser_location_text_view
и справа отfollowing_text_view
. Добавим атрибутыandroid:layout_below="@id/user_location_text_view"
иandroid:layout_toEndOf="@+id/following_text_view"
к элементуfollowers_text_view
.activity_user_info.xml
После этого видим, что мы получили такой же
layout
, как в предыдущем уроке:Какие преимущества от того, что мы используем
RelativeLayout
? Мы убрали вложенный контейнерLinearLayout
. В данном примере это было не критично, но вообще важно помнить, что слишком глубокая вложенность приводит к снижению производительности пользовательского интерфейса. Хорошей практикой является вложенность не больше10
уровней.Осталась ещё одна вещь, которую надо помнить, когда используете
RelativeLayout
. Нельзя объявлять круговые (транзитивные) зависимости. Т.е. если мы зададим кнопке свойствоandroid:layout_toStartOf="@+id/search_edit_text"
, а кEditText
добавим зависимостьandroid:layout_toStartOf="@+id/search_button"
, то приложение выдаст исключениеjava.lang.IllegalStateException: Circular dependencies cannot exist in RelativeLayout
. Можете проверить это, если не верите :)Подведём итоги:
RelativeLayout
позволяет элементам указывать зависимости как относительно друг друга, так и относительно сторон самого родительского контейнераRelativeLayout
.RelativeLayout
позволяет избавиться от вложенности контейнеров в отличие отLinearLayout
Полезные материалы:
Полный листинг изменений кода:
Code diff