9、架构层

18 阅读3分钟

Jetpack Compose 架构层

基本架构层

Jetpack Compose 不是一个单体式项目,而是由多层模块组合而成的完整堆栈。了解这些层次结构可以帮助你:

  • 使用适当的抽象级别构建应用
  • 了解何时可以"降级"到较低级别获取更多控制权
  • 最小化依赖项

Compose 的主要架构层(从下到上):

1. 运行时(Runtime)

提供 Compose 的基本组件,如 remembermutableStateOf@Composable 注解和 SideEffect。如果你只需要 Compose 的树管理功能而不需要界面,可以直接基于此层构建。

2. 界面(UI)

包含多个模块(ui-textui-graphicsui-tooling 等),实现界面工具包的基本组件,如 LayoutNode、Modifier、输入处理、自定义布局和绘图。如果只需要界面工具包的基本概念,可以基于此层构建。

3. 基础(Foundation)

为 Compose 界面提供与设计系统无关的构建块,如 RowColumnLazyColumn 和特定手势识别。你可以基于此层构建自己的设计系统。

4. Material

提供 Material Design 系统的实现,包括主题系统、样式化组件、涟漪效果和图标。在应用中使用 Material Design 时,基于此层构建最为合适。

设计原则

1. 精细化组合

Compose 提供可组合的小块功能,而非几个单体式组件。高级组件提供更多功能但控制权较少,你可以"降级"到低级组件获取更多控制:

// 高级 API
val color = animateColorAsState(if (condition) Color.Green else Color.Red)

// 低级 API(提供更多控制)
val color = remember { Animatable(Color.Gray) }
LaunchedEffect(condition) {
    color.animateTo(if (condition) Color.Green else Color.Red)
}

2. 自定义能力

通过组合小构建块,可以轻松按需自定义组件。例如,Material 的 Button 由 4 个组件组合而成:

@Composable
fun Button(
    // …
    content: @Composable RowScope.() -> Unit
) {
    Surface(/* … */) {
        CompositionLocalProvider(/* … */) { // set LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                Row(/* … */ content = content)
            }
        }
    }
}

Button 组合了:

  • Material Surface:提供背景、形状和点击处理
  • CompositionLocalProvider:在启用/禁用按钮时更改内容透明度
  • ProvideTextStyle:设置默认文本样式
  • Row:为按钮内容提供默认布局

3. 按需自定义

当需要超出组件参数的自定义时,可以"降级"到某一层级创建自己的组件:

@Composable
fun GradientButton(
    // …
    background: List<Color>,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(onClick = {})
            .background(Brush.horizontalGradient(background))
    ) {
        CompositionLocalProvider(/* … */) { // set material LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                content()
            }
        }
    }
}

如果不想使用 Material 概念,可以进一步"降级"只使用基础层组件:

@Composable
fun BespokeButton(
    // …
    backgroundColor: Color,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(onClick = {})
            .background(backgroundColor)
    ) {
        // No Material components used
        content()
    }
}

选择合适的抽象级别

Compose 以构建可重复使用的分层组件为理念,不应总是以构建低级构建块为目标。高级组件通常融入了最佳实践(如无障碍功能支持)。

例如,为自定义组件添加手势支持时,应考虑使用合适的抽象级别:

  • 低级:Modifier.pointerInput(从头开始构建)
  • 中级:Modifier.draggableModifier.scrollable
  • 高级:Modifier.swipeable

最佳实践:基于能提供所需功能的最高级别组件构建,以受益于其包含的最佳实践。

提示:如需构建自定义设计系统的示例,可参考 Jetsnack 示例