При создании проекта в предыдущем уроке автоматически были созданы два файла: UserInfoActivity.java и activity_user_info.xml. В целом, это отражает парадигму написания кода при разработке Android приложений: весь код нашего проекта делится на два типа файлов:
xml – файлы с расширением .xml. С их помощью мы создаем разметку элементов отображаемых в нашем приложении, иными словами – пользовательский интерфейс приложения. Для каждого окна (Activity) приложения создается свой xml-файл со своей разметкой. Также их можно включать друг в друга, комбинировать и использовать много раз одну и ту же разметку с помощью дублирования. Как это делается, мы рассмотрим далее.
java – файлы с расширением .java, содержат в себе код, отвечающий за все процессы (бизнес-логику) происходящие в программе.
Итак, у нас есть файл разметки с внешним видом элементов activity_user_info.xml и файл, который приводит в действие эти элементы UserInfoActivity.java. Android Studio по умолчанию связала наши UserInfoActivity.java и activity_user_info.xml в методе onCreate() класса UserInfoActivity. Если кто-то не помнит (не знает) жизненный цикл Activity, то будет полезно освежить знания, посмотрев этот урок.
Весь экран, который нам предстоит сделать в ближайшие уроки выглядит так:
Вначале нам необходимо сделать эту часть экрана:
В первую очередь необходимо абстрагироваться и разбить экран на блоки, чтобы представить структуру файла xml. Визуально это можно представить прямоугольниками с именами элементов и их id. Выглядит это так:
Затем надо проанализировать расположение элементов. Очень важно уделить этому время, чтобы потом ничего не пришлось переделывать. Можно заметить, что первые пять элементов расположены линейно вертикально (один находится под другим), а два последних элемента линейно горизонтально относительно друг друга.
Элементы View, ViewGroup
Здесь самое время вспомнить (узнать) немного базовой теории об элементах пользовательского интерфейса в Android.
Внутри xml-файлов все элементы делятся на два вида – элементы и контейнеры, с помощью которых можно объединять несколько элементов:
элементы – это компоненты View. С английского это можно перевести как отображение. Мы отображаем разные элементы в нашей разметке. View-компоненты – это просто прямоугольники на экране, границы которых мы можем видеть, а можем и не видеть. И все базовые компоненты расширяют View-компонент: TextView, EditText, Button, Spinner, CheckBox. У каждого элемента есть свои свойства такие как ширина, высота, размеры, цвета и многое другое. Все эти свойства меняются с помощью соответствующих атрибутов (android:layout_width, android:layout_height, android:background и т.д.).
контейнеры называются ViewGroup, что означает группа элементов. Внутрь контейнера можно поместить любые элементы (текст, картинки, кнопки, другие контейнеры (т.к. ViewGroup в свою очередь также является View)). Они служат для удобства, чтобы мы могли группировать элементы экрана и тем самым создавать удобную структуру, с нам будет удобно работать.
Для линейного расположения элементов в Android есть контейнер LinearLayout (рус. линейный макет). Если кто-то не знаком с ним, то можно посмотреть этот урок. Мы будем использовать его в качестве главного контейнера для нашего layout. У LinearLayout есть атрибут android:orientation="vertical | horizontal". Мы будем использовать значение vertical потому что элементы расположены вертикально.
Теперь создадим layout, в соответствии нашим описанием. Для того, чтобы видеть расположение элементов необходимо наполнить их каким-то содержимым(текстом, изображением). К элементу ImageView добавим атрибут android:src . Это необходимо для того, чтобы отрисовалась хоть какая-то картинка (мы укажем ссылку на стандартную картинку android:src="@mipmap/ic_launcher"). К нашим TextView добавим атрибут android:text, присвоив им соответствующие значения. Наш файл activity_user_info.xml будет выглядеть так:
Android Studio подсвечивает значения атрибутов android:text, предлагая заменить их на строковые ресурсы. Т.к. мы используем эти атрибуты временно, потом мы их просто удалим, то просто игнорируем это замечание.
Когда вы просто создаёте layout, то лучше не запускать приложение каждый раз (т.к. это отнимет гораздо больше времени), а посмотреть результат, нажав кнопку Preview в правой верхней части экрана или нажав на вкладку Design:
Этот режим удобен, когда вам не надо видеть мелкие элементы, требующие детальной проработки. Если же вам надо увидеть layout крупнее, то вы можете нажать вкладку Design снизу и увеличить zoom:
Пока у нас получилась довольно сырая версия нашего экрана. Давайте подумаем, что нужно доработать:
добавить вертикальные отступы между элементами;
увеличить размер текста в элементах TextView;
добавить отступ у всех элементов по левому краю;
расположить элементы following_text_view и followers_text_view горизонтально в одной строке.
Первое, что мы исправим – вертикальное расстояние между элементами. Для этого есть два свойства:
android:padding (top, bottom, right | end, start | left)
android:layout_margin (top, bottom, right | end, start | left)
Параметры (top, bottom, right | end, start | left) означают, с какой стороны вы хотите сделать отступ. Параметры right | end, start | left означают практически одно и тоже. Только start, end добавляют поддержку для стран, в которых тексты читаются справа налево. Поэтому рекомендуется использовать их вместо left, right. Эти атрибуты поддерживаются с 17 версии устройств, значит мы можем их использовать (помните, что при создании проекта мы указали, что поддерживаем устройства 17 версии и выше).
Если указать padding без всякого параметра, то отступ будет сделан со всех сторон. Основное различие двух атрибутов состоит в том, что padding делает отступ внутри элемента, а layout_margin делает отступ снаружи. Покажем это на примере. Как говорилось ранее, View-компоненты – это просто прямоугольники, которые отображаются на экране. И иногда для целей проверки каких-либо наших решений в xml-файлах удобно пользоваться свойством, которое присутствует у каждого View-компонента – android:background. Задавая ему какой-либо цвет явно выделяющийся на экране мы можем чётко увидеть границы, занимаемые нашим элементом для проверки соответствия отрисованного на экране с тем, что мы желали бы там видеть.
Таким образом, давайте отредактируем атрибуты первых двух TextView, а всё остальное оставим неизменным:
activity_user_info.xml
<LinearLayout>
<!--Остальные элементы сверху не изменились -->
<TextViewandroid:id="@+id/user_name_text_view"android:text="Имя"android:background="@color/colorPrimary"android:paddingTop="20dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
<TextViewandroid:id="@+id/user_nick_text_view"android:text="Ник"android:background="@color/colorPrimary"android:layout_marginTop="20dp"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
<!-- Остальные элементы снизу не изменились-->
</LinearLayout>
В результате увидим:
То есть видим, что границы элемента user_name_text_view увеличились. Границы элемента стали занимать больше места, потому что мы указали ему высоту и ширину wrap_content (рус. упаковывать содержимое) и визуально образовался отступ для текста. А user_nick_text_view занимает столько же места, сколько и текст в нём, потому что layout_marginTop задаёт отступ снаружи элемента. В случаях, когда нам не нужно увеличивать размеры самого элемента (это и есть наш случай), лучше использовать свойство layout_marginTop.
Давайте удалим свойства background, marginTop, paddingTop из наших TextView для дальнейшей работы.
Так, с отступом между элементами мы разобрались. Давайте добавим к каждому TextView атрибут увеличения вертикального отступа (а заодно увеличим и размера шрифта):
Следующий шаг – добавление отступа у всех элементов по левому краю. Можно добавить всем элементам атрибут layout_marginStart. Но давайте подумаем, что будет, если в layout добавятся ещё 20 новых TextView? Придётся добавлять это свойство в каждый элемент. А если надо будет изменить размер отступа? Это будет задача не из простых, точнее не из быстрых. Все элементы находятся внутри одного LinearLayout. Помните, что padding делает отступы внутри элемента? Это именно тот случай, когда надо применить этот атрибут. Укажем атрибут padding для LinearLayout. Причём по рекомендациям Google padding у контейнеров должен быть симметричный (одинаковый со всех сторон).
activity_user_info.xml
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:padding="8dp"android:layout_height="match_parent"android:layout_width="match_parent">
<!--Остальные элементы внутри не изменились -->
</LinearLayout>
Посмотрим результат:
Нам осталось выполнить последнее задание в этом уроке. Необходимо расположить элементы following_text_view и followers_text_view горизонтально в одной строке. Помните, на рисунке с блоками элементов мы их визуально объединили ещё в один прямоугольник? Чтобы расположить их горизонтально мы можем также использовать LinearLayout, в который вложим два этих элемента. Давайте для двух последних TextView в нашем layout сделаем контейнер LinearLayout. Т.к. мы хотим расположить наши элементы горизонтально, то используем атрибут android:orientation="horizontal" у нашего LinearLayout.
Выглядит это так:
activity_user_info.xml
<LinearLayout>
<!--Остальные элементы выше не изменились -->
<LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal">
<TextViewandroid:id="@+id/following_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:text="Читает"android:textSize="16sp"/>
<TextViewandroid:id="@+id/followers_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:text="Читатели"android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
В результате:
Важно, что атрибуты android:layout_width, android:layout_height у LinearLayout имеют значение wrap_content. Это значит, что контейнер занимает ровно столько места, сколько необходимо его вложенным элементам.
Нам необходимо добавить отступ между элементами внутри. Давайте добавим атрибут android:layout_marginStart="10dp" элементу, стоящему справа(followers_text_view).
Также мы можем перенести повторяющийся атрибут layout_marginTop в их контейнер. Это лучше сделать, чтобы при изменениях величины менять её в минимальном количестве мест. Учитывая все замечания, получим:
activity_user_info.xml
...
<LinearLayout>
<!--Остальные элементы выше не изменились -->
<LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="5dp"android:orientation="horizontal">
<TextViewandroid:id="@+id/following_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Читает"android:textSize="16sp"/>
<TextViewandroid:id="@+id/followers_text_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="10dp"android:text="Читатели"android:textSize="16sp"/>
</LinearLayout>
</LinearLayout>
Посмотрим, что получилось:
Что ж, в этом уроке мы создали основу для отображения данных пользователя, используя контейнер LinearLayout. В следующем уроке на практике познакомимся с контейнером RelativeLayout.
Полезные материалы:
Сайт использует cookie-файлы для того, чтобы вам было удобнее им пользоваться. Для
продолжения работы с сайтом, вам необходимо принять использование cookie-файлов.
Код начала урока:
gitzip
Структура урока:
Видео версия урока
Создание layout экрана.
При создании проекта в предыдущем уроке автоматически были созданы два файла:
UserInfoActivity.java
иactivity_user_info.xml
. В целом, это отражает парадигму написания кода при разработкеAndroid
приложений: весь код нашего проекта делится на два типа файлов:xml
– файлы с расширением.xml
. С их помощью мы создаем разметку элементов отображаемых в нашем приложении, иными словами – пользовательский интерфейс приложения. Для каждого окна (Activity
) приложения создается свойxml
-файл со своей разметкой. Также их можно включать друг в друга, комбинировать и использовать много раз одну и ту же разметку с помощью дублирования. Как это делается, мы рассмотрим далее.java
– файлы с расширением.java
, содержат в себе код, отвечающий за все процессы (бизнес-логику) происходящие в программе.Итак, у нас есть файл разметки с внешним видом элементов
activity_user_info.xml
и файл, который приводит в действие эти элементыUserInfoActivity.java
.Android Studio
по умолчанию связала нашиUserInfoActivity.java
иactivity_user_info.xml
в методеonCreate()
классаUserInfoActivity
. Если кто-то не помнит (не знает) жизненный циклActivity
, то будет полезно освежить знания, посмотрев этот урок.Весь экран, который нам предстоит сделать в ближайшие уроки выглядит так:
Вначале нам необходимо сделать эту часть экрана:
В первую очередь необходимо абстрагироваться и разбить экран на блоки, чтобы представить структуру файла
xml
. Визуально это можно представить прямоугольниками с именами элементов и ихid
. Выглядит это так:Затем надо проанализировать расположение элементов. Очень важно уделить этому время, чтобы потом ничего не пришлось переделывать. Можно заметить, что первые пять элементов расположены линейно вертикально (один находится под другим), а два последних элемента линейно горизонтально относительно друг друга.
Элементы View, ViewGroup
Здесь самое время вспомнить (узнать) немного базовой теории об элементах пользовательского интерфейса в Android.
Внутри
xml
-файлов все элементы делятся на два вида – элементы и контейнеры, с помощью которых можно объединять несколько элементов:View
. С английского это можно перевести как отображение. Мы отображаем разные элементы в нашей разметке.View
-компоненты – это просто прямоугольники на экране, границы которых мы можем видеть, а можем и не видеть. И все базовые компоненты расширяютView
-компонент:TextView
,EditText
,Button
,Spinner
,CheckBox
. У каждого элемента есть свои свойства такие как ширина, высота, размеры, цвета и многое другое. Все эти свойства меняются с помощью соответствующих атрибутов (android:layout_width
,android:layout_height
,android:background
и т.д.).ViewGroup
, что означает группа элементов. Внутрь контейнера можно поместить любые элементы (текст, картинки, кнопки, другие контейнеры (т.к.ViewGroup
в свою очередь также являетсяView
)). Они служат для удобства, чтобы мы могли группировать элементы экрана и тем самым создавать удобную структуру, с нам будет удобно работать.Для линейного расположения элементов в
Android
есть контейнерLinearLayout
(рус. линейный макет). Если кто-то не знаком с ним, то можно посмотреть этот урок. Мы будем использовать его в качестве главного контейнера для нашегоlayout
. УLinearLayout
есть атрибутandroid:orientation="vertical | horizontal"
. Мы будем использовать значениеvertical
потому что элементы расположены вертикально.Теперь создадим
layout
, в соответствии нашим описанием. Для того, чтобы видеть расположение элементов необходимо наполнить их каким-то содержимым(текстом, изображением). К элементуImageView
добавим атрибутandroid:src
. Это необходимо для того, чтобы отрисовалась хоть какая-то картинка (мы укажем ссылку на стандартную картинкуandroid:src="@mipmap/ic_launcher"
). К нашимTextView
добавим атрибутandroid:text
, присвоив им соответствующие значения. Наш файлactivity_user_info.xml
будет выглядеть так:activity_user_info.xml
Android Studio
подсвечивает значения атрибутовandroid:text
, предлагая заменить их на строковые ресурсы. Т.к. мы используем эти атрибуты временно, потом мы их просто удалим, то просто игнорируем это замечание.Когда вы просто создаёте
layout
, то лучше не запускать приложение каждый раз (т.к. это отнимет гораздо больше времени), а посмотреть результат, нажав кнопкуPreview
в правой верхней части экрана или нажав на вкладкуDesign
:Этот режим удобен, когда вам не надо видеть мелкие элементы, требующие детальной проработки. Если же вам надо увидеть
layout
крупнее, то вы можете нажать вкладкуDesign
снизу и увеличить zoom:Пока у нас получилась довольно сырая версия нашего экрана. Давайте подумаем, что нужно доработать:
TextView
;following_text_view
иfollowers_text_view
горизонтально в одной строке.Первое, что мы исправим – вертикальное расстояние между элементами. Для этого есть два свойства:
android:padding (top, bottom, right | end, start | left)
android:layout_margin (top, bottom, right | end, start | left)
Параметры
(top, bottom, right | end, start | left)
означают, с какой стороны вы хотите сделать отступ. Параметрыright | end
,start | left
означают практически одно и тоже. Толькоstart, end
добавляют поддержку для стран, в которых тексты читаются справа налево. Поэтому рекомендуется использовать их вместоleft, right
. Эти атрибуты поддерживаются с 17 версии устройств, значит мы можем их использовать (помните, что при создании проекта мы указали, что поддерживаем устройства 17 версии и выше).Если указать
padding
без всякого параметра, то отступ будет сделан со всех сторон. Основное различие двух атрибутов состоит в том, чтоpadding
делает отступ внутри элемента, аlayout_margin
делает отступ снаружи. Покажем это на примере. Как говорилось ранее,View
-компоненты – это просто прямоугольники, которые отображаются на экране. И иногда для целей проверки каких-либо наших решений вxml
-файлах удобно пользоваться свойством, которое присутствует у каждогоView
-компонента –android:background
. Задавая ему какой-либо цвет явно выделяющийся на экране мы можем чётко увидеть границы, занимаемые нашим элементом для проверки соответствия отрисованного на экране с тем, что мы желали бы там видеть.Таким образом, давайте отредактируем атрибуты первых двух
TextView
, а всё остальное оставим неизменным:activity_user_info.xml
В результате увидим:
То есть видим, что границы элемента
user_name_text_view
увеличились. Границы элемента стали занимать больше места, потому что мы указали ему высоту и ширинуwrap_content
(рус. упаковывать содержимое) и визуально образовался отступ для текста. Аuser_nick_text_view
занимает столько же места, сколько и текст в нём, потому чтоlayout_marginTop
задаёт отступ снаружи элемента. В случаях, когда нам не нужно увеличивать размеры самого элемента (это и есть наш случай), лучше использовать свойствоlayout_marginTop
.Давайте удалим свойства
background
,marginTop
,paddingTop
из нашихTextView
для дальнейшей работы.Так, с отступом между элементами мы разобрались. Давайте добавим к каждому
TextView
атрибут увеличения вертикального отступа (а заодно увеличим и размера шрифта):activity_user_info.xml
И получим:
Следующий шаг – добавление отступа у всех элементов по левому краю. Можно добавить всем элементам атрибут
layout_marginStart
. Но давайте подумаем, что будет, если вlayout
добавятся ещё 20 новыхTextView
? Придётся добавлять это свойство в каждый элемент. А если надо будет изменить размер отступа? Это будет задача не из простых, точнее не из быстрых. Все элементы находятся внутри одногоLinearLayout
. Помните, чтоpadding
делает отступы внутри элемента? Это именно тот случай, когда надо применить этот атрибут. Укажем атрибутpadding
дляLinearLayout
. Причём по рекомендациям Googlepadding
у контейнеров должен быть симметричный (одинаковый со всех сторон).activity_user_info.xml
Посмотрим результат:
Нам осталось выполнить последнее задание в этом уроке. Необходимо расположить элементы
following_text_view
иfollowers_text_view
горизонтально в одной строке. Помните, на рисунке с блоками элементов мы их визуально объединили ещё в один прямоугольник? Чтобы расположить их горизонтально мы можем также использоватьLinearLayout
, в который вложим два этих элемента. Давайте для двух последнихTextView
в нашемlayout
сделаем контейнерLinearLayout
. Т.к. мы хотим расположить наши элементы горизонтально, то используем атрибутandroid:orientation="horizontal"
у нашегоLinearLayout
.Выглядит это так:
activity_user_info.xml
В результате:
Важно, что атрибуты
android:layout_width
,android:layout_height
уLinearLayout
имеют значениеwrap_content
. Это значит, что контейнер занимает ровно столько места, сколько необходимо его вложенным элементам.Нам необходимо добавить отступ между элементами внутри. Давайте добавим атрибут
android:layout_marginStart="10dp"
элементу, стоящему справа(followers_text_view
).Также мы можем перенести повторяющийся атрибут
layout_marginTop
в их контейнер. Это лучше сделать, чтобы при изменениях величины менять её в минимальном количестве мест. Учитывая все замечания, получим:activity_user_info.xml
Посмотрим, что получилось:
Что ж, в этом уроке мы создали основу для отображения данных пользователя, используя контейнер
LinearLayout
. В следующем уроке на практике познакомимся с контейнеромRelativeLayout
.Полезные материалы:
Полный листинг изменений кода:
Code diff