样式方面的正确做法和错误做法

本页介绍了使用样式以在整个代码库中实现一致性的最佳实践,以及我们在设计 API 时遵循的原则。

正确做法

请遵循以下最佳实践:

建议:使用样式来设置视觉效果,使用修饰符来设置行为

使用 Styles API 进行视觉配置(背景、内边距、边框),并预留修饰符以用于点击逻辑、手势检测或无障碍功能等行为。

操作:在设计系统中公开样式参数

对于您自己的自定义设计系统组件,您应在修饰符参数之后公开一个 Style 对象。

@Composable
fun GradientButton(
    modifier: Modifier = Modifier,
    // ✅ DO: for design system components, expose a style modifier to consumers to be able to customize the components
    style: Style = Style
) {
    // Consume the style
}

操作:将基于视觉效果的参数替换为样式

考虑将可组合项上的参数替换为单个 Style 参数。例如:

// Before
@Composable
fun OldButton(background: Color, fontColor: Color) {
}

// After
// ✅ DO: Replace visual-based parameters with a style that includes same properties
@Composable
fun NewButton(style: Style = Style) {
}

做法:优先考虑动画的样式

使用内置的 animate 代码块进行基于状态的样式设置,并使用动画来提高性能,而不是使用修饰符。

做法:利用“后写胜出”

利用 style 属性会覆盖而非堆叠的特性。 使用此属性可替换默认的组件边框或背景,而无需使用多个参数。

禁忌行为

不建议采用以下模式:

不要:使用样式来定义互动逻辑

请勿尝试在样式中处理 onClick 或手势检测。样式仅限于基于状态的视觉配置,因此不应处理业务逻辑;相反,它们应仅根据状态具有不同的视觉效果。

错误做法:将默认样式作为默认参数提供

样式参数应始终使用 style: Style = Style 进行声明:

@Composable
fun BadButton(
    modifier: Modifier = Modifier,
    // ❌ DON'T set a default style here as a parameter
    style: Style = Style { background(Color.Red) }
) {
}

如需添加“默认”参数,请将传入的参数样式与定义的默认样式合并:

@Composable
fun GoodButton(
    modifier: Modifier = Modifier,
    // ✅ Do: always pass it as a Style, do not pass other defaults
    style: Style = Style
) {
    // ...
    val defaultStyle = Style { background(Color.Red) }
    // ✅ Do Combine defaults inside with incoming parameter
    Box(modifier = modifier.styleable(styleState, defaultStyle, style)) {
      // your logic
    }
}

请勿:向基于布局的可组合项提供样式参数

虽然您可以为任何可组合项提供样式,但基于布局的可组合项或屏幕级可组合项不应接受样式 - 从消费者的角度来看,不清楚样式在此级别会做什么。 样式是为组件设计的,不一定适用于布局。