第一篇:Jetpack Compose 宣言——为什么 Android 开发需要声明式 UI

290 阅读3分钟

1.1 从 XML 到 Compose:Android UI 的进化简史

在 Jetpack Compose 出现之前,Android UI 开发经历了两个时代:

时代一:XML + findViewById(2010-2015)

<!-- activity_main.xml -->
<TextView
    android:id="@+id/greeting"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World" />
// MainActivity.java
TextView greeting = findViewById(R.id.greeting);
greeting.setText("Welcome back!");

痛点:findViewById 冗长、类型不安全、View 与逻辑分离导致维护成本高。后来有了 ButterKnife / ViewBinding 缓解,但治标不治本。

时代二:MVC/MVP/MVVM(2015-2020) 架构上不断演进,但 UI 层的命令式更新本质未变——开发者始终需要手动管理 View 的状态:

// 即使有了 ViewBinding,仍然需要手动同步状态
binding.nameText.text = user.name
binding.nameText.visibility = if (user.isVIP) View.VISIBLE else View.GONE
binding.avatar.setImageURI(user.avatar)

每一个状态字段都需要一行更新代码。当 UI 复杂度上升,updateUI() 方法会膨胀到难以维护。

1.2 声明式 UI 是什么

命令式 UI(传统方式):你告诉 UI "怎么做"

textView.text = "Hello"  // 第一步
textView.setTextColor(Color.RED)  // 第二步
textView.visibility = VISIBLE  // 第三步

声明式 UI(Compose 方式):你告诉 UI "是什么"

@Composable
fun Greeting(name: String) {
    Text(
        text = "Hello $name",
        color = Color.Red,
        modifier = Modifier.padding(8.dp)
    )
}

核心区别:

维度命令式(View 系统)声明式(Compose)
更新方式手动操作 View 实例自动重组
状态来源分散各处单一数据源
组件复用自定义 ViewComposable 函数
布局方式XML + 运行时Kotlin DSL
数据流双向/可变单向/不可变

声明式 UI 并非 Compose 首创——SwiftUI(2019)、Flutter(2017)、React(2013)早已验证了这一范式。Google 在 2021 年正式发布 Compose 稳定版,标志着 Android 进入声明式 UI 时代。

1.3 Compose 的三层架构

Compose 架构分为三层,从底层到上层:

┌──────────────────────────────────┐
│         Material Design          │  Material 组件、主题
├──────────────────────────────────┤
│            Foundation            │  基础布局、手势、语义
├──────────────────────────────────┤
│              UI                  │  Modifier、布局、绘制、输入
├──────────────────────────────────┤
│          Runtime                 │  Compose 编译器、Slot Table、重组
└──────────────────────────────────┘
  • Runtime:Compose 的核心运行时,包含重组机制、Slot Table、状态追踪
  • UI:基础 UI 原语,Modifier 系统,Canvas 绘制,触摸事件
  • Foundation:Material 之上的基础组件,提供布局容器、手势系统
  • Material:Material Design 3 规范的具体实现

这种分层设计意味着你可以:

  • 直接使用 Material 组件快速开发
  • 用 Foundation + UI 做自定义组件
  • 脱离 Material,只在 Runtime 之上构建自己的 UI 体系

1.4 Compose 的核心优势

更强的可组合性

传统自定义 View 通过继承复用:

class CustomButton extends AppCompatButton { ... }

Compose 通过组合复用:

@Composable
fun CustomButton(text: String, onClick: () -> Unit) {
    Surface(shape = RoundedCornerShape(8.dp)) {
        Button(onClick = onClick) {
            Text(text)
        }
    }
}

组合优于继承——这是 Compose 的设计哲学。你可以通过嵌套已有的小组件来构建复杂 UI,而不需要继承任何基类。

更少的模板代码

传统方式:layout XML + Activity/Fragment + Adapter + ViewHolder

Compose 方式:一个 Composable 函数即可。以 RecyclerView 为例,传统需要至少 4 个文件,Compose 只需要几行 LazyColumn。

预览与迭代效率

@Preview(showBackground = true, showSystemUi = true)
@Composable
fun GreetingPreview() {
    MyAppTheme {
        Greeting("Android")
    }
}

可组合函数天然支持 Android Studio 预览,支持交互模式、多设备预览、主题切换,无需每次修改都编译运行。

1.5 Compose 当前生态(2026)

截止 2026 年,Compose 已成为 Android 官方推荐的 UI 开发方式:

  • 稳定版:Compose BOM 2026.x,完全可用于生产
  • Compose MultiplatformJetBrains 官方支持,跨 Android / iOS / Desktop / Web
  • 三方生态:Coil(图片加载)、Landscapist、Voyager、Decompose 等三方库成熟
  • Google 趋势:新项目默认启用 Compose,Play Store 头部应用已大规模采用

1.6 本章小结

内容要点
演进历史XML → ViewBinding → Compose,UI 开发效率持续提升
声明式范式描述"是什么"而非"怎么做",状态驱动 UI 自动更新
三层架构Runtime → UI → Foundation → Material,层层递进
核心优势组合优于继承、更少模板、高效预览
生态现状2026 年 Compose 已是 Android 开发主流

下一篇动手搭建第一个 Compose 项目,从 Hello World 开始你的 Compose 之旅。


本系列所有代码基于 Compose BOM 2026.x,Kotlin 2.x,Android Studio Ladybug / Koala 版本。