Прямые ссылки на публичные уроки для быстрого старта и стабильной индексации lesson-страниц.
Давайте пройдемся по теории. В чем идея, зачем Jetpack Compose вообще появился и почему все так хотят писать на нем.
Я расскажу поверхностно про историю разработки на XML, обращая внимание на нововведения и неудобства этого подхода. А в конце сравним всё с Compose, чтобы была наглядно видна эволюция подхода к разработке и очевидны преимущества декларативного фреймворка.
Раньше для создания пользовательского интерфейса использовались XML-файлы, в которых описывалась большая часть компонентов — кнопки, текстовые поля, контейнеры и так далее. Верстка была на языке разметки XML в виде вложенной структуры данных, что в целом удобно, поскольку UI тоже имеет вложенную структуру.
Проектирование интерфейса на XML было похоже на создание дерева. Android сам парсил XML-файлы и создавал иерархию объектов View в памяти. Каждый элемент экрана — кнопка, текстовое поле или изображение — наследуется от базового класса View, а контейнеры от ViewGroup.
Также разработчики могли визуально рисовать интерфейсы и сразу видеть их в визуальном редакторе. Такой подход называется WYSIWYG — what you see is what you get. Качество превью оставляет желать лучшего, но это лучше, чем ничего.
Надо сказать, что базовые классы и их наследники огромны: перегружены логикой и имеют сложную иерархию. Их тяжело поддерживать и расширять, особенно при создании кастомных компонентов, что увеличивает время на разработку.
Система должна отображать всю эту иерархию на экране, и перерисовка интерфейса могла существенно влиять на производительность. Мы только строим дерево и взаимодействуем с ним, вызывая функции классов. При изменении параметров приходится перегруппировывать элементы, выполнять новый расчет размеров и делать множественные вызовы метода measure. Эффективность зависит от качества верстки и глубины вложенности контейнеров. Плюс при работе с XML неизбежна стадия инфлейтинга.
В первые годы разработчики применяли императивный подход: изменения UI происходили напрямую в разных частях кода. Централизованное управление состоянием появилось значительно позже.
Понятие состояния как единого "источника правды" (source of truth) начало набирать популярность с появлением архитектурных паттернов MVP и MVVM. Разработчики поняли преимущества подхода, где стейт отрисовывается в UI: мы просто меняем состояние, а UI автоматически обновляется — вспоминаем механизм подписки через Observer.
Например, UI-стейт во ViewModel в виде LiveData или StateFlow: подписываемся и полностью отображаем его в интерфейсе, не смешивая логику и отрисовку.
Jetpack Compose сочетает лаконичный язык с моделью реактивного программирования. Реактивное программирование — это подход, при котором система автоматически реагирует на изменения данных, не требуя ручной проверки состояния.
В Compose ты описываешь, как должен выглядеть UI в зависимости от состояния данных, а система сама обновляет интерфейс. Нет необходимости вручную подписываться на LiveData или StateFlow — всё работает автоматически. Перерисовываются только те компоненты, которые действительно изменились, а не весь интерфейс целиком.
Это новый виток эволюции в Android по части работы с состоянием. Подробности раскроем в следующих уроках.
Стейты упростили разработчикам жизнь, но верстать в XML всё равно остается неудобно:
Такие мелочи сильно замедляют разработку. Даже если превью показывает правильный результат в 90% случаев, всё равно приходится компилировать и проверять вручную. А это занимает время — самый ценный ресурс программиста.
Тезисно вспомним неудобства XML и как Compose их устраняет:
View-классам: каждый элемент интерфейса — это функция, описывающая его внешний вид и поведение.В целом здесь только основные тезисы в пользу Compose — всю мощь и прелесть вы ощутите, когда начнете разрабатывать на нем.
В следующем уроке рассмотрим что такое DSL в Jetpack Compose, Scope функции, а также разницу между императивным и декларативным подходом в Android.