Skip to content

编程思想

源:Compose 编程思想

Jetpack Compose 是一个声明式 UI 框架。要用好它,需要从根本上转变看待 UI 的方式:从“修改视图”转变为“描述视图”。

声明式 vs 命令式

核心差异

  • 命令式 (Imperative): 告诉机器“怎么做”。例如:nameView.setText("Virogu")
  • 声明式 (Declarative): 告诉机器“是什么”。例如:Text(text = "Virogu")

核心思维模型

1. UI 是状态的函数

在 Compose 中,UI 是不可变的,无法在创建后进行更新。触发 UI 更新的唯一方式是改变状态 (State)

公式

$$ UI = f(State) $$ 当 $State$ 发生变化时,函数 $f$ 重新运行,产生新的 $UI$。

2. 重组 (Recomposition)

当状态更新时,Compose 会再次调用可组合函数。这个过程称为重组

重组的五个特性(点击展开)
  1. 可组合函数可以按任何顺序执行:不要依赖上一个函数的执行结果。
  2. 可组合函数可以并行运行:Compose 会通过在多个线程上运行可组合函数来利用多核。
  3. 重组会跳过尽可能多的内容:如果参数没变,Compose 会智能跳过该函数的重组。
  4. 重组是乐观的操作:Compose 预计在参数再次更改之前完成重组。如果参数在完成之前更改,Compose 可能会取消重组并以新参数重新开始。
  5. 可组合函数可能会非常频繁地运行:例如在动画期间,每帧都会运行。

3. 单向数据流 (UDF)

单向数据流是一种设计模式,状态向下流动,事件向上流动。

kotlin
@Composable
fun Counter(count: Int, onIncrement: () -> Unit) {
    Column {
        Text("Count: $count") // 状态向下流动
        Button(onClick = onIncrement) { // 事件向上流动
            Text("Increment")
        }
    }
}
kotlin
@Composable
fun BadCounter() {
    var count = 0 // 这样定义变量重组时会重置
    Button(onClick = { count++ }) { // 事件直接修改局部变量,无法触发更新
        Text("Increment: $count")
    }
}