Внимательный зритель по скриншотам наверняка подметил, что кнопки у нас теперь не одноцветные, а градиентные. Да и вообще градиенты очень ходовая штука в новом дизайне. Это вам не просто цвета поменять уже.
В Compose есть две основные сущности, описывающие как делать какую-либо заливку – это Color и Brush. Первый – это когда вам надо что-то в один цвет покрасить, второй – для любого другого случая, в частности для градиентов.
И если вы почему-то думали, что вы просто так можете Material компонентам сказать, что они теперь должны залиться градиентом – это не так. Единственное место, где вы можете безболезненно заменить Color на Brush – это Modifier.background() или другие похожие функции из foundation. У них почти всегда есть версия и для того и для другого. А у любой фигни из Material типа Button, Surface, CircularProgressIndicator, Switch и других в параметрах всегда только Color. 🔫
Что делать? Для начала, чтобы унифицировать использование обоих, мы решили завести какой-то враппер заливки, типа такого:
sealed interface Fill {
data class Solid(val color: Color) : Fill
data class Gradient(val brush: Brush) : Fill
}
// Пример использования
fun Modifier.background(
fill: Fill,
shape: Shape = RectangleShape,
): Modifier = when (fill) {
is Fill.Solid -> background(fill.color, shape)
is Fill.Gradient -> background(fill.brush, shape)
}
В свои компоненты мы теперь всегда передаём его, а не Color, как раньше было. Изменили параметры, но внутри компонентов то что делать?
Переписывать, что ещё. На практике для Compose это значит, что вытаскиваем кишки компонентов к себе, до тех пор пока где-нибудь не появится голый Modifier или что-то, чему можно и Color и Brush дать. 🍑
Например, не используем material.Button внутри своего компонента, а вытаскиваем из него Surface для клика, а в нём делаем Box с переопределённым бэкграундом. Или лезем доставать внутренности CircularProgressIndicator до drawArc, потому что у него то Brush задать можно, в отличие от всех родительских функций. У каждого компонента там под капотом что-то своё, но идея почти всегда такая.
Сами "заливки" можно воспринимать как новые токены дизайн-системы и динамически их пересобирать. В зависимости от того же бренда они могут быть жёлтым солидом или фиолетово-синим градиентом, и это больше не потребует трогать параметры самих компонентов.
Опять хочется поругать гугл за то, что на классный foundation у них отстойный material. Написать приложение без него почти невозможно, а кастомизируется он с трудом. Нам нужно что-то гибкое посередине между foundation и material. И вот такую обёртку не забудьте, пожалуйста.