[Разработка под Android] Compose. Jetpack Compose
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Благодаря стремительному развитию мобильной индустрии каждые несколько лет мы наблюдаем появления новых технических решений, призванных усложнить упростить жизнь разработчикам. Некоторые из них, не сыскав популярности у пользователей, остаются лишь частью истории, другие – плотно укореняются в повседневной разработке, становясь в определенной области стандартом де-факто.
Пожалуй, главным трендом мобильной разработки за последние несколько лет стал декларативный UI. Такое решение уже давно успешно применяется в веб и кроссплатформенных решениях и, наконец, добралось и до нативной разработки. На iOS существует SwiftUI (представленный на WWDC 2019), а на Android – Jetpack Compose (представленный месяцем ранее на Google I/O 2019). И именно о последнем мы сегодня и поговорим.
Примечание: в данной статье мы не будем рассматривать поэтапное создание первого проекта на Compose, так как этот процесс прекрасно описан в других материалах. Моя цель – лишь рассказать о преимуществах и недостатках, которые дает android-разработчикам переход на Jetpack Compose, а решение использовать или нет всегда остаётся за вами.
Появление
Официальная история Jetpack Compose начинается с мая 2019, когда он был представлен публике на конференции Google I/O. «Простой, реактивный и Kotlin-only» – новый декларативный фреймворк от Google выглядел как младший брат Flutter (который к тому моменту уже стремительно набирал популярность).
API design is building future regret
О недостатках текущего UI-фреймворка Android было сказано и написано уже достаточно большое количество раз. Проблемы с View-иерархией, зависимость от релизов платформы – наличие этих и множества других мелких недостатков в той или иной мере доставляли неудобства разработчикам, что и побудило компанию Google заняться разработкой нового фреймворка, способного решить все эти проблемы.
Преимущества
Итак, чем же хорош Jetpack Compose и, главное, чем он кардинально отличается от существующего на данный момент UI-фреймворка Android?
- Unbundled toolkit: JC не зависит от конкретных релизов платформы, а значит, забудем уже про Support Library.
- Kotlin-only: Больше не нужно переключаться между классами и xml-файлами – вся работа с UI происходит в одном Kotlin-файле.
- Композитный подход: Наследованию – нет, композиции – да. Каждый UI-компонент представляет собой обычную composable-функцию, отвечающую только за ограниченный функционал, т.е. без лишней логики. Никаких больше View.java на 30 тысяч строк кода.
- Unidirectional Data Flow: Одна из основополагающих концепций Jetpack Compose, о которой будет рассказано подробнее чуть ниже.
- Обратная совместимость: Для использования Compose не требуется начинать проект с нуля. Имеется возможность как его встраивания (с помощью ComposeView) в имеющуюся xml-вёрстку, так и наоборот.
- Меньше кода: Тут, как говорится, «лучше один раз увидеть, чем сто раз услышать». В качестве примера возьмём классическое сочетание компонентов – два поля ввода и кнопка подтверждения:
В реализации текущего UI-фреймворка вёрстка этих компонентов выглядит так:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:padding="@dimen/padding_16dp">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:hint="@string/sign_in_email"
android:layout_marginBottom="@dimen/margin_8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/til_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:hint="@string/sign_in_password"
android:layout_marginVertical="@dimen/margin_8dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/et_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"/>
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/btn_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/sign_in_submit"
android:layout_marginTop="@dimen/margin_8dp"
android:padding="@dimen/padding_8dp"
android:background="@color/purple_700"/>
</LinearLayout>
В то же время, при использовании Jetpack Compose, решение будет выглядеть следующим образом:
@Preview
@Composable
fun LoginPage(){
var loginValue by remember { mutableStateOf(TextFieldValue("")) }
var passwordValue by remember { mutableStateOf(TextFieldValue("")) }
Surface(color = Color.White) {
Column(modifier = Modifier.padding(16.dp).fillMaxWidth()) {
Surface(color = Color.White, modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp))) {
OutlinedTextField(
value = loginValue,
onValueChange = { loginValue = it },
label = { Text(text = stringResource(id = R.string.sign_in_email)) },
placeholder = { Text(text = stringResource(id = R.string.sign_in_email)) },
modifier = Modifier.fillMaxWidth()
)
}
Surface(color = Color.White, modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp))) {
OutlinedTextField(
value = passwordValue,
onValueChange = { passwordValue = it },
label = { Text(text = stringResource(id = R.string.sign_in_password)) },
placeholder = { Text(text = stringResource(id = R.string.sign_in_password)) },
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier.fillMaxWidth()
)
}
Button(
onClick = {},
modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp)).fillMaxWidth(),
backgroundColor = colorResource(R.color.purple_700)) {
Text(text = stringResource(id = R.string.sign_in_submit), modifier = Modifier.padding(8.dp))
}
}
}
}
Ну и напоследок – сравнительный результат:
Недостатки
- Alpha-версия: Безусловно, более чем за год разработки фреймворк значительно преобразился и стал гораздо стабильнее. Однако это всё ещё альфа, а поэтому за пределами Pet-проектов использовать его не рекомендуется.
Декларативный стиль
Отдельное внимание стоит уделить главной особенности Jetpack Compose – декларативному стилю создания UI. Суть подхода заключается в описании интерфейса как совокупности composable-функций (они же виджеты), которые не используют «под капотом» view, а напрямую занимаются отрисовкой на canvas. Для кого-то это минус, для других – возможность попробовать что-то новое. Так или иначе, к концепции «верстать UI кодом» нативному разработчику, не работавшему ранее с аналогичными технологиями (к примеру, Flutter или React Native), придётся привыкать.
Что за Unidirectional Data Flow?
В современном android-приложении UI-состояние меняется в зависимости от приходящих событий (нажатие на кнопку, переворот экрана и т.д.). Мы нажимаем на компонент, тем самым формируя событие, а компонент меняет свой state и вызывает callback в ответ. Из-за довольно тесной связи UI-состояния с View это потенциально может привести к усложнению поддержки и тестирования такого кода. К примеру, возможна ситуация, когда помимо внутреннего state компонента, мы можем хранить его состояние в поле (например во viewmodel), что теоретически может привести к бесконечному циклу обновления этого самого state.
Что же касается Jetpack Compose, то здесь все компоненты по умолчанию являются stateless. Благодаря принципу однонаправленности нам достаточно «скормить» модель данных, а любое изменение состояния фреймворк обработает за нас. Таким образом, логика компонента упрощается, а инкапсуляция состояния позволяет избежать ошибок, связанных с его частичным обновлением. В качестве примера возьмем уже рассмотренный ранее composable-код. Перед описание компонентов были определены две переменные:
var loginValue by remember { mutableStateOf(TextFieldValue("")) }
var passwordValue by remember { mutableStateOf(TextFieldValue("")) }
Мы создаем два текстовых объекта, значения которых будем устанавливать полям ввода (логина и пароля) в качестве value. А благодаря связке remember { mutableStateOf(…) } любое изменение значений этих объектов (из других частей кода) уведомит об этом соответствующее поле ввода, которое перерисует только значение value, вместо полной рекомпозиции всего компонента.
Вывод
Какой же вывод можно сделать о Jetpack Compose? По моему мнению, у нового решения от Google имеется огромный потенциал. С момента анонса в 2019 году была проделана огромная работа, и не менее долгий путь до релиза у фреймворка ещё впереди. Однако теперь он публично доступен, и я считаю, что это прекрасная возможность познакомиться с ним поближе. Ну а за чем, по вашему мнению, будущее – пишите в комментарии, будет интересно узнать ваше мнение. Любите android!
===========
Источник:
habr.com
===========
Похожие новости:
- [Монетизация мобильных приложений, Платежные системы, Разработка мобильных приложений, Разработка под Android] Таргетирование уведомлений, управление ценами в разных регионах и другие возможности HMS для интернет-платежей
- [Разработка под iOS, Разработка под Android, Карьера в IT-индустрии, Конференции, Flutter] 22 октября приглашаем на онлайн-митап Hot Mobile: iOS, Android, Flutter
- [Java, Анализ и проектирование систем, Промышленное программирование, Распределённые системы] Интеграция в стиле BPM
- [Разработка под Android, Хакатоны, Kotlin, Искусственный интеллект] Челлендж по разговорному ИИ на хакатоне Junction: создай чатбота или голосовой навык и выиграй 10 000 евро
- [Java, Разработка мобильных приложений, Разработка под Android, Kotlin, Gradle] Встраиваем аналитику от Huawei в Android приложение
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android, Монетизация мобильных приложений] На Apps Live 2020 вас ждет не только классика — будем завоёвывать Поднебесную
- [MySQL, Администрирование баз данных, DevOps] Mysql 8.x Group Replication (Master-Slave) with Docker Compose
- [Аналитика мобильных приложений, Разработка мобильных приложений] Дайджест главных новостей мобайла и ASO за месяц
- [Разработка под iOS, Разработка мобильных приложений, Разработка под Android, Управление проектами, Управление продуктом] Как сэкономить на разработке мобильного приложения
- Google будет раскрывать сведения об уязвимостях в сторонних Android-устройствах
Теги для поиска: #_razrabotka_pod_android (Разработка под Android), #_jetpack_compose, #_android, #_compose, #_android_studio, #_jetpack, #_android_sdk, #_declarative_ui, #_declarative, #_unidirectional, #_kotlin, #_blog_kompanii_epam (
Блог компании EPAM
), #_razrabotka_pod_android (
Разработка под Android
)
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 15:38
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Благодаря стремительному развитию мобильной индустрии каждые несколько лет мы наблюдаем появления новых технических решений, призванных усложнить упростить жизнь разработчикам. Некоторые из них, не сыскав популярности у пользователей, остаются лишь частью истории, другие – плотно укореняются в повседневной разработке, становясь в определенной области стандартом де-факто. Пожалуй, главным трендом мобильной разработки за последние несколько лет стал декларативный UI. Такое решение уже давно успешно применяется в веб и кроссплатформенных решениях и, наконец, добралось и до нативной разработки. На iOS существует SwiftUI (представленный на WWDC 2019), а на Android – Jetpack Compose (представленный месяцем ранее на Google I/O 2019). И именно о последнем мы сегодня и поговорим. Примечание: в данной статье мы не будем рассматривать поэтапное создание первого проекта на Compose, так как этот процесс прекрасно описан в других материалах. Моя цель – лишь рассказать о преимуществах и недостатках, которые дает android-разработчикам переход на Jetpack Compose, а решение использовать или нет всегда остаётся за вами. Появление Официальная история Jetpack Compose начинается с мая 2019, когда он был представлен публике на конференции Google I/O. «Простой, реактивный и Kotlin-only» – новый декларативный фреймворк от Google выглядел как младший брат Flutter (который к тому моменту уже стремительно набирал популярность). API design is building future regret
О недостатках текущего UI-фреймворка Android было сказано и написано уже достаточно большое количество раз. Проблемы с View-иерархией, зависимость от релизов платформы – наличие этих и множества других мелких недостатков в той или иной мере доставляли неудобства разработчикам, что и побудило компанию Google заняться разработкой нового фреймворка, способного решить все эти проблемы. Преимущества Итак, чем же хорош Jetpack Compose и, главное, чем он кардинально отличается от существующего на данный момент UI-фреймворка Android?
В реализации текущего UI-фреймворка вёрстка этих компонентов выглядит так: <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:padding="@dimen/padding_16dp"> <com.google.android.material.textfield.TextInputLayout android:id="@+id/til_login" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:hint="@string/sign_in_email" android:layout_marginBottom="@dimen/margin_8dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/et_login" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="text"/> </com.google.android.material.textfield.TextInputLayout> <com.google.android.material.textfield.TextInputLayout android:id="@+id/til_password" android:layout_width="match_parent" android:layout_height="wrap_content" style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox" android:hint="@string/sign_in_password" android:layout_marginVertical="@dimen/margin_8dp"> <com.google.android.material.textfield.TextInputEditText android:id="@+id/et_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword"/> </com.google.android.material.textfield.TextInputLayout> <Button android:id="@+id/btn_confirm" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/sign_in_submit" android:layout_marginTop="@dimen/margin_8dp" android:padding="@dimen/padding_8dp" android:background="@color/purple_700"/> </LinearLayout> В то же время, при использовании Jetpack Compose, решение будет выглядеть следующим образом: @Preview
@Composable fun LoginPage(){ var loginValue by remember { mutableStateOf(TextFieldValue("")) } var passwordValue by remember { mutableStateOf(TextFieldValue("")) } Surface(color = Color.White) { Column(modifier = Modifier.padding(16.dp).fillMaxWidth()) { Surface(color = Color.White, modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp))) { OutlinedTextField( value = loginValue, onValueChange = { loginValue = it }, label = { Text(text = stringResource(id = R.string.sign_in_email)) }, placeholder = { Text(text = stringResource(id = R.string.sign_in_email)) }, modifier = Modifier.fillMaxWidth() ) } Surface(color = Color.White, modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp))) { OutlinedTextField( value = passwordValue, onValueChange = { passwordValue = it }, label = { Text(text = stringResource(id = R.string.sign_in_password)) }, placeholder = { Text(text = stringResource(id = R.string.sign_in_password)) }, visualTransformation = PasswordVisualTransformation(), modifier = Modifier.fillMaxWidth() ) } Button( onClick = {}, modifier = Modifier.padding( vertical = dimensionResource(id = R.dimen.padding_8dp)).fillMaxWidth(), backgroundColor = colorResource(R.color.purple_700)) { Text(text = stringResource(id = R.string.sign_in_submit), modifier = Modifier.padding(8.dp)) } } } } Ну и напоследок – сравнительный результат: Недостатки
Декларативный стиль Отдельное внимание стоит уделить главной особенности Jetpack Compose – декларативному стилю создания UI. Суть подхода заключается в описании интерфейса как совокупности composable-функций (они же виджеты), которые не используют «под капотом» view, а напрямую занимаются отрисовкой на canvas. Для кого-то это минус, для других – возможность попробовать что-то новое. Так или иначе, к концепции «верстать UI кодом» нативному разработчику, не работавшему ранее с аналогичными технологиями (к примеру, Flutter или React Native), придётся привыкать. Что за Unidirectional Data Flow? В современном android-приложении UI-состояние меняется в зависимости от приходящих событий (нажатие на кнопку, переворот экрана и т.д.). Мы нажимаем на компонент, тем самым формируя событие, а компонент меняет свой state и вызывает callback в ответ. Из-за довольно тесной связи UI-состояния с View это потенциально может привести к усложнению поддержки и тестирования такого кода. К примеру, возможна ситуация, когда помимо внутреннего state компонента, мы можем хранить его состояние в поле (например во viewmodel), что теоретически может привести к бесконечному циклу обновления этого самого state. Что же касается Jetpack Compose, то здесь все компоненты по умолчанию являются stateless. Благодаря принципу однонаправленности нам достаточно «скормить» модель данных, а любое изменение состояния фреймворк обработает за нас. Таким образом, логика компонента упрощается, а инкапсуляция состояния позволяет избежать ошибок, связанных с его частичным обновлением. В качестве примера возьмем уже рассмотренный ранее composable-код. Перед описание компонентов были определены две переменные: var loginValue by remember { mutableStateOf(TextFieldValue("")) }
var passwordValue by remember { mutableStateOf(TextFieldValue("")) } Мы создаем два текстовых объекта, значения которых будем устанавливать полям ввода (логина и пароля) в качестве value. А благодаря связке remember { mutableStateOf(…) } любое изменение значений этих объектов (из других частей кода) уведомит об этом соответствующее поле ввода, которое перерисует только значение value, вместо полной рекомпозиции всего компонента. Вывод Какой же вывод можно сделать о Jetpack Compose? По моему мнению, у нового решения от Google имеется огромный потенциал. С момента анонса в 2019 году была проделана огромная работа, и не менее долгий путь до релиза у фреймворка ещё впереди. Однако теперь он публично доступен, и я считаю, что это прекрасная возможность познакомиться с ним поближе. Ну а за чем, по вашему мнению, будущее – пишите в комментарии, будет интересно узнать ваше мнение. Любите android! =========== Источник: habr.com =========== Похожие новости:
Блог компании EPAM ), #_razrabotka_pod_android ( Разработка под Android ) |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 15:38
Часовой пояс: UTC + 5