User Interface
Со всеми приложениями пользователь взаимодействует через интерфейс - User Interface (UI). Ранее мы уже затрагивали тему создание интерфейса, а в данном блоке рассмотрим эту тему детальнее.
Основы
Для дальнейшей практики можно пройти уроки из официального Android курса - Building app UI. Вы сможете:
- Начать создавать более интерактивные приложения.
- Понять, как работают композиция и рекомпозиция.
- Создать приложение, которое работает с данными, введенными пользователем.
- Узнать, как использовать состояние для отображения данных и автоматического отражения изменений при обновлении данных.
Как продолжение темы знакомства с UI хорошо подойдет CodeLab Display lists and use Material Design Вы сможете:
- Создать в приложении прокручиваемый список, отображающий как текст, так и изображения.
- Добавить обработчики кликов для взаимодействия с элементами списка.
- Добавить в приложение панель инструментов и изменить тему оформления.
- Использовать Material Design для создания современных и интуитивно понятных пользовательских интерфейсов, применяя цвета, формы и типографику.
Навигация и верстка экрана
Современные Android‑приложения по‑прежнему строятся по подходу Single Activity, где в качестве экранов используются Composable‑функции, а навигация между ними осуществляется с помощью Jetpack Navigation для Compose.
Для построения навигации Google рекомендует использовать Navigation Compose — это часть Jetpack Navigation, адаптированная для работы с Compose. Она позволяет описывать навигационный граф декларативно, так же как и UI.
Простейшая схема выглядит так:
- одно
Activity - внутри неё —
setContent { } - корневой
NavHost - отдельные Composable‑экраны, зарегистрированные в навигационном графе
Более подробно изучить работу с навигацией и попрактиковаться можно в кодлабе Navigation in Compose
Обязательно прочитайте про передачу данных между компонентами. В контексте Compose это означает:
- как правильно передавать аргументы между composable‑экранами через
NavController - почему следует передавать идентификаторы данных (id), а не сами объекты
- как реализовать строгое и типобезопасное API маршрутов (например, через sealed class или отдельные объекты маршрутов)
- как использовать
ViewModelдля хранения и разделения состояния между экранами
Важно помнить: Composable‑функции не должны хранить бизнес‑логику или состояние, переживающее конфигурационные изменения. Для этого используются ViewModel и архитектурные компоненты.
Верстка UI в Android на данный момент возможна двумя способами:
- Jetpack Compose - новый, современный подход, declarative UI
- XML layouts - устаревший подход
Для знакомсттва с Jetpack Compose подойдет набор уроков от Google - Jetpack Compose
Layout в Jetpack Compose
В Jetpack Compose больше нет XML‑разметки и привычных ViewGroup (ConstraintLayout, LinearLayout и т.д.). Интерфейс описывается декларативно с помощью Composable‑функций.
Основные инструменты для построения UI:
Column— вертикальное расположение элементовRow— горизонтальное расположениеBox— наложение элементов друг на другаSpacer,Modifier.padding(),Modifier.fillMaxSize()и другие модификаторы для управления отступами, размерами и позиционированием
В большинстве случаев комбинации Row, Column, Box и Modifier достаточно для описания сложного интерфейса без глубокой вложенности.
Прочитайте дополнительно Thinking in Compose
Списки (LazyColumn и LazyRow)
Важный элемент практически всех мобильных приложений — список элементов.
В Jetpack Compose вместо RecyclerView используются LazyColumn и LazyRow.
Они:
- отображают только видимые элементы (ленивая подгрузка)
- автоматически переиспользуют composable‑элементы
- не требуют создания Adapter и ViewHolder
Для более сложных случаев доступны:
itemsIndexedkeyдля стабильной идентификации элементовLazyVerticalGridдля сеток/таблиц
Подробнее можно прочитать здесь: Lists in Compose
Связь UI и кода
UI и логика описываются в одном языке (Kotlin), а состояние передаётся в composable‑функции через параметры.
Основной принцип — state hoisting:
- состояние хранится вне composable (например, в
ViewModel) - composable получает состояние через параметры
- изменения состояния передаются наружу через события (callback)
Для хранения состояния, переживающего конфигурационные изменения, используется ViewModel.
AndroidX & Jetpack
В текущем блоке мы использовали разные библиотеки от AndroidX и Jetpack. Разберемся с тем что это за библиотеки.
AndroidX - набор библиотек, обеспечивающих поддержку более новых API на старых версиях устройств. Они позволяют разработчику не задумываться о том, на какой версии android будет запускаться приложение, когда требуемый функционал менялся между разными релизами android. В прошлом этот набор библиотек назывался Android Support Libraries. Рекомендуется использовать AndroidX API, так как оно обновляется чаще релизов Android OS и может включать множество разных багфиксов (как и новых багов, куда без них).
Jetpack - набор библиотек (включающий и AndroidX), предоставляющий множество готовых решения для разных типовых задач разработки приложений - базы данных, архитектурные компоненты, работа с постраничной загрузкой, удобная работа с камерой и прочее (список библиотек большой, можно посмотреть на сайте).
Забота о User Experience (UX)
Разработчики приложений должны стремиться к удобному и понятному пользовательскому опыту. Важно помнить, что мы пишем код не для себя, а чтобы пользователи могли получить приложение которое решает их задачи. Приложение может приносить боль при использовании, а может быть приятным, быстрым и удобным. Ставьте себя на место пользователя, когда делаете какой либо функционал, и спрашивайте "а пользовался бы я сам таким решением?".
Как сделать приложение удобнее и понятнее - можно прочитать на сайте material.io - разделы Interaction и Communication очень детально и наглядно объясняют, как можно создавать опыт комфортного использования приложения. Многие принципы применимы не только на android, но и на любой системе с UI.
Изменения конфигурации
Некоторые конфигурации мобильных устройств могут измениться во время работы приложения. Это могут быть, например, ориентация экрана при повороте устройства пользователем, увеличение пользователем размера шрифта, смена локализации, смена темного режима на светлый и наоборот. В процессе создания приложения нужно помнить о необходимости обработки изменений конфигурации. Прочитайте документацию Google про обработку смены конфигурации.
Practice time
Сделать приложение по дизайну.
- Создать приложение с шаблона
Empty Activity - Создать
data class Contact(val firstName: String, val lastName: String, val avatarResourceId: Int) - Объявить глобальное свойство
contacts: List<Contact>, в котором написать 5 или больше разных контактов - это будут данные нашего приложения - Добавить 2 Composable экрана -
ContactsScteenиContactScreen - На экране
ContactsScteenрасположитьLazyColumn, отрисовывающий множество элементов - разные контакты - На экране
ContactScreenс помощьюColumnиRowсверстать UI экрана просмотра контакта - С помощью Jetpack Navigation сделать переходы между списком и просмотром контакта
- Удостовериться в том, что приложение корректно обрабатывает смену конфигурации: локализации, темы, ориентации экрана, увеличение шрифта