Урок 1. Создание Activity и работа с LinearLayout на примере UserInfoScreen

Код начала урока:

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, то будет полезно освежить знания, посмотрев этот урок.

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

 

UserInfoScreen.png

 

Вначале нам необходимо сделать эту часть экрана:

 

UserInfoLayout.png

 

В первую очередь необходимо абстрагироваться и разбить экран на блоки, чтобы представить структуру файла xml. Визуально это можно представить прямоугольниками с именами элементов и их id. Выглядит это так:

 

UserInfoLayoutBlocks.png

 

Затем надо проанализировать расположение элементов. Очень важно уделить этому время, чтобы потом ничего не пришлось переделывать. Можно заметить, что первые пять элементов расположены линейно вертикально (один находится под другим), а два последних элемента линейно горизонтально относительно друг друга.

Элементы 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_height="match_parent"
    android:layout_width="match_parent">

    <ImageView
        android:id="@+id/user_image_view"
        android:src="@mipmap/ic_launcher"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/user_name_text_view"
        android:text="Имя"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/user_nick_text_view"
        android:text="Ник"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/user_description_text_view"
        android:text="Описание"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/user_location_text_view"
        android:text="Местоположение"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/following_text_view"
        android:text="Читает"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/followers_text_view"
        android:text="Читатели"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

 

Android Studio подсвечивает значения атрибутов android:text, предлагая заменить их на строковые ресурсы. Т.к. мы используем эти атрибуты временно, потом мы их просто удалим, то просто игнорируем это замечание.

Когда вы просто создаёте layout, то лучше не запускать приложение каждый раз (т.к. это отнимет гораздо больше времени), а посмотреть результат, нажав кнопку Preview в правой верхней части экрана или нажав на вкладку Design:

 

UserInfoLayoutV1Preview.png

 

Этот режим удобен, когда вам не надо видеть мелкие элементы, требующие детальной проработки. Если же вам надо увидеть layout крупнее, то вы можете нажать вкладку Design снизу и увеличить zoom:

 

UserInfoLayoutV1Desing.png

 

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

  • добавить вертикальные отступы между элементами;
  • увеличить размер текста в элементах 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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<LinearLayout>

    <!--Остальные элементы сверху не изменились -->

    <TextView
        android: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"/>

    <TextView
        android: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>

 

В результате увидим:

 

UserInfoLayoutPaddingMargin.png

 

То есть видим, что границы элемента user_name_text_view увеличились. Границы элемента стали занимать больше места, потому что мы указали ему высоту и ширину wrap_content (рус. упаковывать содержимое) и визуально образовался отступ для текста. А user_nick_text_view занимает столько же места, сколько и текст в нём, потому что layout_marginTop задаёт отступ снаружи элемента. В случаях, когда нам не нужно увеличивать размеры самого элемента (это и есть наш случай), лучше использовать свойство layout_marginTop.

Давайте удалим свойства background, marginTop, paddingTop из наших TextView для дальнейшей работы.

Так, с отступом между элементами мы разобрались. Давайте добавим к каждому TextView атрибут увеличения вертикального отступа (а заодно увеличим и размера шрифта):

 

activity_user_info.xml

1
2
android:layout_marginTop="5dp"
android:textSize="16sp"

 

И получим:

 

UserInfoLayoutV1MarginTextSize.png

 

Следующий шаг – добавление отступа у всех элементов по левому краю. Можно добавить всем элементам атрибут layout_marginStart. Но давайте подумаем, что будет, если в layout добавятся ещё 20 новых TextView? Придётся добавлять это свойство в каждый элемент. А если надо будет изменить размер отступа? Это будет задача не из простых, точнее не из быстрых. Все элементы находятся внутри одного LinearLayout. Помните, что padding делает отступы внутри элемента? Это именно тот случай, когда надо применить этот атрибут. Укажем атрибут padding для LinearLayout. Причём по рекомендациям Google padding у контейнеров должен быть симметричный (одинаковый со всех сторон).

 

activity_user_info.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<LinearLayout
    xmlns: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>

 

Посмотрим результат:

 

UserInfoLayoutContainerPadding.png

 

Нам осталось выполнить последнее задание в этом уроке. Необходимо расположить элементы following_text_view и followers_text_view горизонтально в одной строке. Помните, на рисунке с блоками элементов мы их визуально объединили ещё в один прямоугольник? Чтобы расположить их горизонтально мы можем также использовать LinearLayout, в который вложим два этих элемента. Давайте для двух последних TextView в нашем layout сделаем контейнер LinearLayout. Т.к. мы хотим расположить наши элементы горизонтально, то используем атрибут android:orientation="horizontal" у нашего LinearLayout.

Выглядит это так:

 

activity_user_info.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<LinearLayout>

    <!--Остальные элементы выше не изменились -->

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/following_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:text="Читает"
            android:textSize="16sp"/>

        <TextView
            android: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>

 

В результате:

 

UserInfoLayoutNestedContainer.png

 

Важно, что атрибуты android:layout_width, android:layout_height у LinearLayout имеют значение wrap_content. Это значит, что контейнер занимает ровно столько места, сколько необходимо его вложенным элементам.

Нам необходимо добавить отступ между элементами внутри. Давайте добавим атрибут android:layout_marginStart="10dp" элементу, стоящему справа(followers_text_view).

Также мы можем перенести повторяющийся атрибут layout_marginTop в их контейнер. Это лучше сделать, чтобы при изменениях величины менять её в минимальном количестве мест. Учитывая все замечания, получим:

 

activity_user_info.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
...
<LinearLayout>

    <!--Остальные элементы выше не изменились -->

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/following_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Читает"
            android:textSize="16sp"/>

        <TextView
            android: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>

 

Посмотрим, что получилось:

 

Result.png

 

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

Полный листинг изменений кода:

Code diff

УВИДЕТЬ ВСЕ Добавить заметку
Вы
Добавить ваш комментарий