Как стать автором
Обновить

Комментарии 9

Спасибо за разбор, но вы немного поспешили, официальный анонс артефактов и codelabs только через неделю на DevSummit. Для работы плагина нужна будет новая студия, новый AGP и ещё не релизнутый Kotlin Compiler с API для плагинов. Как пишут разработчики Compose в slack канале что оно сейчас работает, это скорее случайность :) Сейчас не все фичи будут работать без нового компилятора.


Compose работает на Reflection, вместо Kotlin Compiler Plugin, как это было заявлено ранее

Он не будет работать на рефлексии. Ему нужен компиляторный плагин. В официальном slack канале Compose, Leland Richardson уже ответил на вопрос касательно kotlin.reflect:


i think compose used some reflection very early on and the dependency just never got removed;
update: reflect is going away. kapt is not a dependency and never was.

Спасибо за дополнение. Хотелось показать, что работает, и что не работает на сегодняшний день.
Будем ждать DevSummit. После него попробую применить к моему экрану то, что там покажут, и посмотреть, что улучшится.

Спасибо за статью и обзор текущего доступного API.
Как уже заметили выше в комментариях, ни рефлексии, ни kapt не будет — это зависимости, которые остались в проекте со времени, когда работа над Compose только стартовала. Также, дополняя комментарий выше, какой-то более-менее сложный UI в текущей версии студии скорее будет падать с ошибкой, а те примеры, что работают сейчас, условно говоря, «под капотом» работают неправильно.
Ну и я бы посоветовал добавить в статью, что весь публичный API, который сейчас доступен, нужно рассматривать исключительно с точки зрения dev-preview, а это значит, что он (наверняка) может значительно измениться и в продакшен Compose можно тянуть только под собственную ответственность :)

Напоследок посоветую неплохой доклад с недавнего минского GDG митапа про то, что в Compose вряд ли изменится, а именно — основные принципы его работы: www.youtube.com/watch?v=oK8CFrZmVrg
Привет! Я работаю над Jetpack Compose и хотелось прокоментировать несколько замечаний из статьи.
Во первых, спасибо! Очень подробный и интересный разбор. Приятно что в проекте вам оказалось достаточно легко сориентироваться даже при отсутствии официальной документации. И рад что наши сэмплы помогают.
1) Могу подтвердить то, что ответил sergeyfitis. Версия dev01 это не официальный релиз, а откатка процесса релиза для такого большого проекта. Jetpack Compose все еще требует специальную версию студии, AGP и котлина.
2) Минимальная поддерживаемая версия такой и останется — 21. Мы завязываемся на некоторые апи которые появились в этой версии. Плюс проект еще довольно далек от стейбл версии, надеюсь к тому моменту все больше приложений перейдут на данный minSdkVersion.
3) Автоматическое подхватывание темы из андроид стилей еще не существует. Мы еще рассматриваем как это лучше всего решить. В том числе планируется поддержка dark mode из коробки (тоже еще не до конца реализовано)
4) Чтобы вручную не проставлять +themeColor { onBackground } на каждый Text можно обернуть весь «экран» в Surface {… }, тогда весь текст автоматически перекрасится в onSurface из темы. или же можно использовать Surface(color = +themeColor { background }) {… }, тогда текст перекрасится в onBackground. Думаю логика понятна. Еще до конца не решили будем ли автоматически закрашивать фон в background с применением текста onBackground
5) Тестирование на основе View и их айди перестанет работать, да. Работаем над новым апи для тестирования Compose Ui. Можно посмотреть примеры здесь: android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/ui/ui-material/src/androidTest/java/androidx/ui/material/CheckboxUiTest.kt
6) Все функции вызывающие другие @Composable функции будет необходимо тоже помечать @Composable. Аналогично с тем как работают suspend функции. В дальнейшем такой код не помеченный аннотацией будет ошибкой компиляции.
7) «свойства для виджетов превратились в отдельные виджеты (Center вместо android:gravity, Padding вместо android:margin, …)» — это еще не финальное решение. На данный момент мы изучаем возможность вместо них использовать идею layout modifier. Тут есть примеры: android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/PaddingSample.kt
8) «У кнопки параметр onClick сделан не последним». На данный момент это сделано умышлено чтобы можно было отличить несколько вариантов Button. У этой функции есть несколько перегрузок в разными наборами параметров. Например вместо
Button(“Text", { openAppInPlayStore() })
Можно написать
Button(onClick ={ openAppInPlayStore() }) {
Text(text = «Text», style = ...)
}
Что дает более гибкую настройку текста или даже вызов любого другого Composable вместо текста как контент кнопки
9) Пример про DataTable на самом деле рабочий, как вы видите мы его же используем в нашем семпл приложении: android.googlesource.com/platform/frameworks/support/+/androidx-master-dev/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/DataTableActivity.kt
Как я понимаю разница в том, что у вас получился белый текст на белом фоне. В нашем примере мы еще оборачиваем пример в Surface {}. Как это меняет цвет текста я уже рассказывал выше
10) Аннотация @Model требуется только для классов с мутабельными филдами. Таким образом компайлер сгенерирует дополнительный код в геттеры и сеттеры и каждое изменение поля будет автоматически отслеживаться и вызывать рекомпозицию участка кода, в котором это поле было использовано. Именно таким образом работает +state { DialogVisibleModel(true) }. DialogVisibleModel оборачивается в специальный дата класс с одним var полем и каждый раз когда вы вызываете openDialog.value = DialogVisibleModel(false) все, кто раньше читали значение из openDialog.value автоматически перевызваны чтобы применить изменение
11) «Контекст можно получить, присвоив значение функции setContent{} в onCreateView, но как его использовать, например в Presenter или другом классе, отличном от Fragment или Activity, для изменения состояния – пока непонятно.». Официальная рекомендация на этот вопрос еще не выработана, обязательно скажем как мы советуем это решать после. Например, ваш композабл сможет принимать LiveData или Observable и будет автоматически перерисовываться каждый раз когда новое значение будет доступно из потока
7) Судя по исходникам Modifier кажется довольно объемным решением, можете хоть Padding виджет не удалять, потому что как видно из слака того же — все разделились на 2 лагеря, кому-то удобно через модифаер, кому-то через виджет. Кажется, правильно оставить и поддержать оба варианта.
10) Сейчас если в поле @Model класса есть ArrayList например, то изменение этого листа не влечет за собой изменение UI, нужно присваивать новый ArrayList, что неудобно. Планируется ли как-то улучшить этот процесс, особенно в свете того, что для Compose как раз будут писать свой RecyclerView аналог?
11) А зачем, похоже, что самый удобный способ — это все тот же инстанс @Model внутри ViewModel/Presenter через который и будут производиться изменения. Да и насколько я понимаю с текущей реализацией стейта в Compose LiveData становится ненужной практически.
7) Modifier достаточно объемное решение. мы внутри команды тоже все еще обсуждаем все и взвешиваем. в итоге точно не останется оба варианта, только один будет рекомендованный.
10) Для этой задачи у нас есть специальный вид листа. Он создается через метод modelListOf(). все изменения в нем точно так же вызывают обновление
11) Есть сотни архитектур и подходов. В идеале Compose UI это просто юай слой и он должен работать с любым подходом. На данный момент мы сконцентрированы на этой части. Интеграция с конкретными архитектурами может решаться по разному. Например, как вы заметили, можно прямо модель презентера пометить @Model. Но не все захотят добавлять аннотации к моделям слоя данных и хранить их мутабельными. В этом случае нужны будут какие то потоки данных на которых Compose будет подписываться
Про Modifier жалко, сейчас кажется не очень удобным, учитывая общие концепции типа Ripple {} и тд.
BTW — спасибо за ответы)
Планируется ли нормальная работа с картинками? Хотя бы на уровне того, что есть во Flutter — просто возможность прокинуть Url обычной строкой и все?
Точно так же как в ImageView нельзя передать url точно так же это не задача Image компонента в Compose. Но библиотеки типа условного Glide смогут точно так же очень легко создать условный GlideImage(url: String), который сначала отобразит плейсхолдер, потом пойдет загружать картинку.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации