Прямые ссылки на публичные уроки для быстрого старта и стабильной индексации lesson-страниц.
Начинаем работу в Android Studio. Потихоньку пишем код, попутно разбираясь в том, что пишем. Разбираем что такое Composable функции, что происходит внутри setContent и зачем нужен Scaffold
Открываем пустой проект на Jetpack Compose или создаем новый. Переключаем представление файлов в режим Project, чтобы видеть иерархию так, как она расположена на компьютере.
layout — XML файлы для разметки экранов не используются. Ничто не мешает их создать, и сейчас можно встретить гибридные проекты — чаще всего при плавном переходе команды с XML на Compose. Это тема для отдельного урока.MainActivity со знакомым методом onCreate. Вместо привычного setContentView (принимавшего ID макета) — специальная функция setContent. Внутри её лямбды размещаются Composable функции.ui — здесь предлагается хранить стили, ресурсы цветов и темы. По аналогии с XML, но на Kotlin.Для понимания Composable функций удалим всё лишнее и напишем заново самостоятельно.
enableEdgeToEdge() оставим по умолчанию — эта настройка позволяет приложению использовать всю доступную площадь экрана, включая области под системными элементами (статус-бар, навбар).
Код экрана пишем в методе setContent. Если провалиться в её декларацию, видно, что он расширяет класс Activity, а последний параметр является лямбдой.
Для отображения текста используем функцию Text:
setContent { Text() }
Обратите внимание: функция написана с большой буквы — вопреки обычному стилю Kotlin. Это специальная Composable функция, помеченная аннотацией @Composable. Конкретно Text — стандартная системная. Но мы будем создавать и собственные — для сложного интерфейса и порядка в коде.
Ключевые правила Composable функций:
LocalComposition, на котором строятся темы — о нём позже). При этом Composable функция ничего не возвращает: UI рисуется исключительно за счёт её вызова.В параметрах Text передаём строку с текстом. Название параметра можно указать явно — это удобно при большом количестве параметров.
После запуска текст оказывается в углу экрана. Что происходит?
Раньше макет автоматически учитывал системные отступы и контент размещался ниже статус-бара. Теперь с edge-to-edge дизайном автоматическое добавление отступов отключено — нам предоставляется полный контроль над размещением контента относительно системных баров.
Как решить проблему?
1. Задать отступы конкретному элементу через Modifier. Параметры текста отвечают за внешний вид (цвет, размер, шрифт), а Modifier управляет поведением и размещением (отступы, фон, размеры, обработка кликов). Модификатор универсален и работает с любыми элементами.
Добавим именованный параметр modifier, обратимся к объекту Modifier и вызовем padding. Передав одно значение, задаём все 4 отступа. 70.dp — dp является свойством-расширением класса Int, преобразующим число в пиксели, независимые от плотности экрана.
setContent { Text( text = "AndroidSprint.ru", modifier = Modifier.padding(70.dp) ) }
Текст получает отступы со всех сторон. Но дублировать модификаторы для каждого компонента — неудобно.
2. Создать собственный контейнер с отступами и размещать элементы в нём. Работает, но это костыль.
3. Использовать Composable функцию Scaffold — базовый каркас (от англ. "строительные леса"). Создан для упрощения структуры и автоматизации расположения стандартных элементов. Именно его предлагает использовать среда разработки при создании проекта.
Scaffold и передаём нужные параметры.content отвечает за основное содержимое экрана. Это Composable тип — внутри лямбды размещаем наши Composable функции.PaddingValues — он содержит отступы, которые Scaffold автоматически рассчитывает, чтобы контент не перекрывал системные элементы. Передаём его в метод padding.Scaffold также позволяет добавить TopBar, меню и многое другое. Теперь текст располагается под статус-баром без ручного расчёта отступов.
Дополнительно укажем размер текста через параметр fontSize = 28.sp. sp — то же, что dp, но для размеров шрифтов.
Компоненты помещаются в setContent, однако их будет много, с большим количеством параметров, и многие нужно переиспользовать. Размещать всё в одном методе — значит перегружать onCreate.
Подход такой: создаём кастомные Composable функции с понятными именами, внутри — логика отображения одного или набора элементов. Затем вызываем эти функции в setContent в нужном порядке.
Объявляем функцию как обычную. Название должно отражать суть отрисовываемого — например, StudyAppHeader() для заголовка приложения. Добавляем аннотацию @Composable, внутрь переносим Text. Передадим PaddingValues параметром.
В setContent вместо Text вызываем StudyAppHeader() с параметром паддинга. onCreate разгружен, можно создавать любую логику в виде функций и комбинировать её.
class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Scaffold( content = { innerPadding: PaddingValues -> StudyAppHeader(innerPadding) } ) } } } @Composable fun StudyAppHeader(innerPadding: PaddingValues) { Text( text = "AndroidSprint.ru", fontSize = 28.sp, modifier = Modifier.padding(innerPadding) ) }
Одна из ключевых фич Jetpack Compose — @Preview. Она позволяет отрисовывать Composable функции прямо в Android Studio без сборки проекта и установки APK.
Добавляем аннотацию @Preview к нашей функции — получаем ошибку: превью работает только для методов без параметров.
Создаём отдельную preview-функцию, дописав Preview в название. Делаем её private — чтобы никто из команды не использовал по ошибке. Убираем параметры и вызываем основную функцию, передав пустой PaddingValues().
@Composable @Preview(showBackground = true) private fun StudyAppHeaderPreview() { StudyAppHeader(PaddingValues()) }
Для отображения превью нажимаем кнопку Split в правом верхнем углу. Параметр showBackground = true добавляет фон. Параметр showSystemUi разворачивает превью на полный экран с элементами интерфейса.
Итог: создали Composable функцию StudyAppHeader с отображением текста, вызвали её в Scaffold через параметр content — это обеспечивает стандартный отступ и корректное расположение под статус-баром.
В следующем уроке научимся позиционировать элементы на экране относительно друг друга.