命令式UI (Imperative) 像一份详细的烹饪步骤:你告诉系统“先创建TextView,然后设置文字,再添加到布局……”。而 声明式UI (Declarative) 像一张菜单:“我要一碗牛肉面”,系统负责实现细节。
| 对比维度 | 命令式 (View系统) | 声明式 (Jetpack Compose) |
|---|---|---|
| 编程范式 | 如何做 (How) — 逐步操作UI实例 | 做什么 (What) — 描述UI状态 |
| 状态更新 | 手动 findViewById + setText / 通知适配器 | 状态变化 → 自动重组 (Recomposition) |
| 代码可读性 | 分散在 Activity / Fragment / Adapter | 集中、组合、可预测 |
| 学习曲线 | 传统,但回调嵌套复杂 | 初看陌生,但逻辑连贯 |
| 典型代码 | textView.text = "Hello"
button.setOnClickListener {
textView.text = "Clicked"
} | var text by remember { mutableStateOf("Hello") }
Button(onClick = { text = "Clicked" }) {
Text(text)
} |
@Composable 函数像乐高一样搭建UI,没有复杂的类层次。✦ “UI 是状态的快照” — 当状态改变,Compose 自动重新绘制快照,你只需描述每个状态下的界面。
Jetpack Compose 完全兼容传统 View 体系,可以在同一个界面中混合使用。三种核心互操作模式:
AndroidView 包装任何传统 View (如 MapView, WebView)。ComposeView,调用 setContent。// 在 Compose 中使用传统 View (AndroidView) @Composable fun MapComposable() { AndroidView( factory = { ctx -> MapView(ctx).apply { onCreate(Bundle()) getMapAsync { /* 回调 */ } } }, update = { mapView -> mapView.onResume() } ) } // 在 XML 布局中嵌入 Compose (ComposeView) <androidx.compose.ui.platform.ComposeView android:id="@+id/compose_view" android:layout_width="match_parent" android:layout_height="wrap_content" /> // Activity 中绑定 findViewById<ComposeView>(R.id.compose_view).setContent { MaterialTheme { Greeting("Android + Compose") } }
在 Compose 中,viewModel() 函数让 ViewModel 与 Composable 生命周期绑定。状态通过 StateFlow 或 mutableStateOf 驱动UI。
// ViewModel 示例
class MyViewModel : ViewModel() {
private val _count = MutableStateFlow(0)
val count: StateFlow<Int> = _count.asStateFlow()
fun increment() { _count.value++ }
}
@Composable
fun CounterScreen(viewModel: MyViewModel = viewModel()) {
val count by viewModel.count.collectAsState()
Button(onClick = { viewModel.increment() }) {
Text("点击次数: $count")
}
}