Прямые ссылки на публичные уроки для быстрого старта и стабильной индексации lesson-страниц.
Начинаем подготовку к верстке первого экрана учебного приложения для изучения английских слов. В качестве основы используется дизайн-макет в Figma — представим, что это реальный заказ на разработку.
После создания проекта Android Studio сгенерировала ряд файлов. Сейчас нас интересует основной файл, в котором будем писать код — MainActivity.kt.
Activity — один из базовых системных компонентов Android. Activity представляет собой окно или страницу приложения: то, что видит пользователь и с чем он взаимодействует в данный момент.
MainActivity — обычный класс, который наследуется от AppCompatActivity (базового класса Activity, предоставляющего возможности для разработки Android). Экземпляр MainActivity не создается вручную — он генерируется системой автоматически. Разработчик не вызывает конструктор класса. Достаточно прописать его в AndroidManifest.xml, чтобы система его увидела и использовала.
Манифест — это конфигурационный файл приложения. Все Activity необходимо указывать в нём.
В классе находится переопределённый метод onCreate() — он является частью жизненного цикла Activity. Этот цикл содержит методы, вызываемые в разных состояниях приложения: при старте, сворачивании, уничтожении и т.д.
Внутри onCreate() описывается то, что происходит в момент создания экрана — до того, как его содержимое увидит пользователь. Система создаёт экземпляр MainActivity и вызывает метод жизненного цикла onCreate().
Внутри с помощью ключевого слова super вызывается onCreate() родителя, в параметры которого передаются данные о сохранённом состоянии экрана. Далее необходимо вызвать setContentView().
setContentView() дословно переводится как «установить контент отображения». Метод используется для установки UI-макета для конкретной Activity: мы передаём в него XML-макет с вёрсткой видимого экрана. Таким образом файл макета связывается с файлом экрана — в нашем случае activity_main.xml с MainActivity.kt.
Метод принимает целое число Int — идентификатор файла макета. ID макета, на который мы ссылаемся через R.layout, генерируется автоматически и передаётся в метод в качестве параметра.
Запустим приложение на эмуляторе — видим пустой экран со стандартной надписью «Hello World».
Переходим в файл разметки. В Android Studio существует несколько режимов представления:
Содержимое файла — это XML: формат хранения данных, простой и универсальный.
Интерфейс Android-приложения — это иерархия различных View. View — элементы на экране: текст, кнопки, контейнеры, списки и т.д. Их можно выстраивать в иерархии для создания интерфейса любой сложности. Технически View — это класс, представляющий отрисовываемую часть интерфейса.
В XML-разметке каждый элемент представляется с помощью тегов — они определяют начало и конец элемента, его свойства и содержимое.
Например, для отображения текста используется тег <TextView>. Сначала открывается тег, пишется название, затем перечисляются атрибуты (настройки). В конце тег закрывается символом обратного слеша:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"/>
Допустима и запись с отдельным закрывающим тегом:
<TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent"> </TextView>
Короткая запись используется, когда между тегами нет вложенного контента. Для внешнего тега-контейнера ConstraintLayout закрывающий тег обязателен: открывающий тег с атрибутами → вложенный TextView → закрывающий тег контейнера.
При клике на название тега оно подсвечивается в коде и в превью экрана. Изменим текст в TextView и перезапустим приложение — текст корректно отображается.
<androidx.constraintlayout.widget.ConstraintLayout> — открывающий тег контейнера ConstraintLayout, размещающего элементы с использованием ограничений (constraints). Полное имя компонента с пакетом указывается для библиотечных и самописных UI-компонентов. Короткое название используется для встроенных в SDK компонентов.
Атрибуты xmlns — аббревиатура от «XML Namespace». Они определяют и связывают префиксы с пространствами имён, позволяя использовать определённый набор атрибутов в документе. Используемые префиксы:
Атрибуты layout_width и layout_height отвечают за ширину и высоту элемента. Возможные значения:
150dp.dp (density-independent pixel, пиксель независимый от плотности экрана) — единица измерения расстояний для элементов. Устройства имеют разную плотность пикселей (количество пикселей на дюйм), поэтому использование dp гарантирует автоматическое масштабирование размеров. Это обеспечивает одинаковые пропорции элементов на разных устройствах.
Добавим ещё один текстовый элемент. После закрытия тега видим подсвеченную ошибку: This view is not constrained. Элемент внутри ConstraintLayout обязательно должен иметь ограничители — его нужно «привязать» минимум к двум сторонам из четырёх.
При клике на элемент появляются точки, за которые можно тянуть и привязывать к другим элементам. Чтобы разместить новый текст под имеющимся, тянем его верхнюю грань и прикрепляем к нижней грани другого элемента.
После добавления привязки в коде изменится следующее:
id — android:id="@+id/textView", сгенерированный автоматически. В дальнейшем мы будем прописывать идентификаторы вручную для обращения к ним из MainActivity.Top привязана к стороне Bottom элемента с id textView.Тег по-прежнему подсвечивается красным — нужен минимум второй констрейнт. Потянем правую грань до края экрана — появится значение parent, означающее привязку к краю родительского элемента. Ошибка исчезнет.
ConstraintLayout гибок: если привязать элемент с обеих сторон, он по умолчанию выровняется по центру и будет адаптивно центрироваться на любых устройствах.
Рассмотрим ещё несколько атрибутов TextView:
android:gravity="center" — центрирует содержимое по вертикали и горизонтали. Для раздельного центрирования: center_horizontal и center_vertical. Отличие от layout_gravity рассмотрим на следующем уроке.android:textSize="20sp" — размер текста. Для шрифтов используется единица sp (scalable pixel — масштабируемый пиксель).android:textColor="#7A03AC" — цвет текста в формате HEX. Цвет можно выбрать через встроенную палитру Android Studio.android:textAllCaps="true" — отображает весь текст заглавными буквами (Boolean-значение).Держать в голове все атрибуты для каждого типа View не нужно. Есть два удобных приёма:
Вся актуальная документация также доступна на официальном сайте developer.android.com.
В setContentView() можно передавать любой файл разметки. Чтобы открыть местоположение текущего файла в проекте, используйте кнопку «прицел» (Navigate → Select in Project View) — файл находится в папке res/layout.
Для создания нового файла кликните правой кнопкой по папке layout → New → Layout Resource File. В названии принято указывать сначала тип разметки или назначение, затем через нижнее подчёркивание — уникальное имя. Создадим activity_second.xml (расширение .xml указывать необязательно). В пункте Root Element задаётся корневой контейнер — по умолчанию ConstraintLayout.
Добавим на новый макет кнопку. Начнём вводить Button — Android Studio предложит варианты:
android.widget.Button. Это нужный нам вариант.AppCompatButton — тоже обычная кнопка, но из библиотеки поддержки AppCompat, которая обеспечивает корректную работу UI-компонентов на старых устройствах. Однако система сама при необходимости обращается к этой поддержке — специально использовать компоненты из AppCompat не нужно. Выбираем обычный Button из SDK.
SDK (Software Development Kit), который выбирался при создании проекта, содержит стандартные библиотеки со вспомогательными классами, включая View-компоненты. Убедиться в этом можно, переключившись в режим Project, провалившись в декларацию класса Button и нажав «прицел» в иерархии файлов — Button находится в стандартном SDK.
Центрируем кнопку на экране с помощью констрейнтов, добавляем отступы (margin задаёт отступ для внешней границы элемента — подробнее в следующем уроке), задаём текст атрибутом text и при необходимости задаём конкретную ширину и высоту.
Чтобы новый файл макета отображался в MainActivity вместо activity_main, передаём его идентификатор в setContentView():
setContentView(R.layout.activity_second)
После запуска приложения отобразится созданный макет.