Существует три способа внедрения стилей в ваше приложение:
- Используйте непосредственно в существующих компонентах, которые предоставляют параметр
Style. - Примените стиль с помощью
Modifier.styleableк элементам макета, которые не принимают параметрStyle. - В вашей собственной системе дизайна используйте
Modifier.styleable{}и предоставьте возможность задать параметр стиля для ваших компонентов.
Доступные объекты недвижимости на Styles
Стили поддерживают многие из тех же свойств, что и модификаторы; однако не все, что может быть воспроизведено с помощью стиля. Модификаторы по-прежнему необходимы для определенных действий, таких как взаимодействие, пользовательская отрисовка или наложение свойств.
| Группировка | Характеристики | Наследуется детьми |
|---|---|---|
| Макет и размеры | ||
| Набивка | contentPadding (внутренний) и externalPadding (внешний). Доступны варианты с направленным, горизонтальным, вертикальным и боковым отображением. | Нет |
| Размеры | fillWidth/Height/Size() и width , height и size (поддерживает Dp , DpSize или дробные значения типа Float ). | Нет |
| Позиционирование | Смещение left/top/right/bottom . | Нет |
| Внешний вид | ||
| Заливки | background и foreground (поддерживает Color или Brush ). | Нет |
| Границы | borderWidth , borderColor и borderBrush . | Нет |
| Форма | shape | Нет, но используется в сочетании с другими свойствами. clip и border используется заданная форма. |
| Тени | dropShadow , innerShadow | Нет |
| Трансформации | ||
| Пространственное перемещение графического слоя | translationX , translationY , scaleX/Y , rotationX/Y/Z | Нет |
| Контроль | alpha , zIndex (порядок наложения) и transformOrigin (точка опоры) | Нет |
| Типография | ||
| Стиль | textStyle , fontSize , fontWeight , fontStyle и fontFamily | Да |
| Окраска | contentColor и contentBrush . Они также используются для стилизации иконок. | Да |
| Абзац | lineHeight , letterSpacing , textAlign , textDirection , lineBreak и hyphens . | Да |
| Украшение | textDecoration , textIndent и baselineShift . | Да |
Используйте стили непосредственно для компонентов с параметрами стиля.
Компоненты, предоставляющие параметр Style , позволяют задавать их стиль:
BaseButton( onClick = { }, style = { } ) { BaseText("Click me") }
Внутри лямбда-функции стиля можно задать различные свойства, такие как externalPadding или background :
BaseButton( onClick = { }, style = { background(Color.Blue) } ) { BaseText("Click me") }
Полный список поддерживаемых свойств см. в разделе «Доступные свойства в стилях» .
Примените стили с помощью модификаторов к компонентам, у которых нет существующих параметров.
Для компонентов, у которых отсутствует встроенный параметр стиля, вы все равно можете применять стили с помощью модификатора styleable . Такой подход также полезен при разработке собственных пользовательских компонентов.
Row( modifier = Modifier.styleable { } ) { BaseText("Content") }
Аналогично параметру style , вы можете включить в лямбда-функцию такие свойства, как background или padding .
Row( modifier = Modifier.styleable { background(Color.Blue) } ) { BaseText("Content") }
Множественные связанные модификаторы Modifier.styleable суммируются с ненаследуемыми свойствами применяемого компонуемого объекта, ведя себя аналогично нескольким модификаторам, определяющим одни и те же свойства. Для наследуемых свойств они переопределяются, и последний модификатор styleable в цепочке устанавливает значения.
При использовании Modifier.styleable вам также может потребоваться создать и передать StyleState , который будет использоваться с модификатором для применения стилей на основе состояния. Для получения более подробной информации см. раздел «Состояние и анимация со стилями» .
Определите самостоятельный стиль
Для удобства повторного использования можно определить отдельный стиль:
val style = Style { background(Color.Blue) }
Затем вы можете передать этот определенный стиль в параметр стиля компонуемого объекта или с помощью Modifier.styleable . При использовании Modifier.styleable вам также необходимо создать объект StyleState . StyleState подробно описан в документации по состоянию и анимации со стилями .
В следующем примере показано, как можно применить стиль либо напрямую через встроенные параметры компонента, либо через Modifier.styleable :
val style = Style { background(Color.Blue) } // built in parameter BaseButton(onClick = { }, style = style) { BaseText("Button") } // modifier styleable val styleState = remember { MutableStyleState(null) } Column( Modifier.styleable(styleState, style) ) { BaseText("Column content") }
Вы также можете передать этот стиль в несколько компонентов:
val style = Style { background(Color.Blue) } // built in parameter BaseButton(onClick = { }, style = style) { BaseText("Button") } BaseText("Different text that uses the same style parameter", style = style) // modifier styleable val columnStyleState = remember { MutableStyleState(null) } Column( Modifier.styleable(columnStyleState, style) ) { BaseText("Column") } val rowStyleState = remember { MutableStyleState(null) } Row( Modifier.styleable(rowStyleState, style) ) { BaseText("Row") }
Добавьте несколько свойств стиля.
Вы можете добавить несколько свойств стиля, задав разные свойства для каждой строки:
BaseButton( onClick = { }, style = { background(Color.Blue) contentPaddingStart(16.dp) } ) { BaseText("Button") }
Свойства в стилях не суммируются, в отличие от стилей, основанных на модификаторах. Стили берут последнее заданное значение из списка свойств в пределах одного блока стиля. В следующем примере, когда фон задан дважды, применяется TealColor . Для отступов contentPaddingTop переопределяет верхний отступ, заданный contentPadding , и не объединяет значения.
BaseButton( style = { background(Color.Red) // Background of Red is now overridden with TealColor instead background(TealColor) // All directions of padding are set to 64.dp (top, start, end, bottom) contentPadding(64.dp) // Top padding is now set to 16.dp, all other paddings remain at 64.dp contentPaddingTop(16.dp) }, onClick = { // } ) { BaseText("Click me!") }

contentPadding .Объединение объектов нескольких стилей
Вы можете создать несколько объектов Style и передать их в параметр style вашего составного объекта.
val style1 = Style { background(TealColor) } val style2 = Style { contentPaddingTop(16.dp) } BaseButton( style = style1 then style2, onClick = { }, ) { BaseText("Click me!") }

contentPaddingTop . Когда несколько стилей задают одно и то же свойство, выбирается последнее заданное свойство. Поскольку свойства в стилях не суммируются, последний переданный отступ переопределяет значение contentPaddingHorizontal , заданное исходным contentPadding . Кроме того, последний цвет фона переопределяет цвет фона, заданный исходным переданным стилем.
val style1 = Style { background(Color.Red) contentPadding(32.dp) } val style2 = Style { contentPaddingHorizontal(8.dp) background(Color.LightGray) } BaseButton( style = style1 then style2, onClick = { }, ) { BaseText("Click me!") }
В данном случае применено оформление со светло-серым фоном и отступом 32.dp , за исключением левого и правого отступов, значение которых равно 8.dp .

contentPadding , значение которого переопределяется различными стилями.Наследование стиля
Некоторые свойства стиля, такие как contentColor и свойства, связанные со стилем текста, передаются дочерним составным элементам. Стиль, установленный для дочернего составного элемента, переопределяет унаследованный стиль родительского элемента для этого конкретного дочернего элемента.

Style , styleable и direct.| Приоритет | Метод | Эффект |
|---|---|---|
| 1 (Наивысший) | Прямые аргументы о составном | Переопределяет все остальные параметры; например, Text(color = Color.Red) |
| 2 | Параметр стиля | Локальные стили переопределяют Text(style = Style { contentColor(Color.Red)} |
| 3 | цепочка модификаторов | Modifier.styleable{ contentColor(Color.Red) в самом компоненте. |
| 4 (самый низкий) | Стили родителей | Для свойств, которые могут быть унаследованы (типографика/цвет), передаваемых от родительского элемента. |
Родительский стиль
Вы можете задавать свойства текста (например, contentColor ) в родительском компоненте, и они будут передаваться всем дочерним компонентам Text .
val styleState = remember { MutableStyleState(null) } Column( modifier = Modifier.styleable(styleState) { background(Color.LightGray) val blue = Color(0xFF4285F4) val purple = Color(0xFFA250EA) val colors = listOf(blue, purple) contentBrush(Brush.linearGradient(colors)) }, ) { BaseText("Children inherit", style = { width(60.dp) }) BaseText("certain properties") BaseText("from their parents") }

Переопределение свойств дочерними элементами
Вы также можете задать стиль для конкретного Text элемента. Если для родительского элемента задан стиль, то стиль, заданный для дочернего элемента, переопределяет стиль родительского элемента.
val styleState = remember { MutableStyleState(null) } Column( modifier = Modifier.styleable(styleState) { background(Color.LightGray) val blue = Color(0xFF4285F4) val purple = Color(0xFFA250EA) val colors = listOf(blue, purple) contentBrush(Brush.linearGradient(colors)) }, ) { BaseText("Children can ", style = { contentBrush(Brush.linearGradient(listOf(Color.Red, Color.Blue))) }) BaseText("override properties") BaseText("set by their parents") }

Реализуйте пользовательские свойства стиля.
Вы можете создавать пользовательские свойства, которые сопоставляются с существующими определениями стилей, используя функции расширения в StyleScope , как показано в следующем примере:
fun StyleScope.outlinedBackground(color: Color) { border(1.dp, color) background(color) }
Примените это новое свойство в определении стиля:
val customExtensionStyle = Style { outlinedBackground(Color.Blue) }
Создание новых стилизуемых свойств не поддерживается. Если для вашего случая необходима такая поддержка, отправьте запрос на добавление функции .
Прочитайте CompositionLocal значения
Распространенным подходом является хранение токенов дизайн-системы внутри CompositionLocal для доступа к переменным без необходимости передачи их в качестве параметров. Стили могут обращаться к CompositionLocal для получения общесистемных значений внутри стиля:
val buttonStyle = Style { contentPadding(12.dp) shape(RoundedCornerShape(50)) background(Brush.verticalGradient(LocalCustomColors.currentValue.background)) }