仓库地址:https://gitee.com/wzj1157362131/compose-learning
适合人群:有 Android XML/View 开发经验、准备系统学习 Jetpack Compose 的工程师


前言:为什么要做这个项目?

做 Android 开发这么多年,XML + View 体系早已烂熟于心。但 Compose 这几年越来越成为官方主推的 UI 方案——新项目默认 Compose、老项目逐步迁移、招聘要求里也开始出现「熟悉 Jetpack Compose」。

问题也很现实:

  • 官方文档很全,但缺少一条能跟着走的练习路线
  • 教程看了很多,代码散落在各处,过几天就找不到了
  • 有 XML 底子,却总在想:「这个在 Compose 里到底对应什么?」

于是我把自己曾经的 Compose 学习过程开源出来,做成一个可运行、可复习、可持续迭代的练手项目——ComposeLearning

这不是一个成品 App,而是一套 「Demo → 讲解 → 作业 → Review → 深度拓展」 的学习工程。本文以第 1 课做完整示范,你照着这个范式就能自学后续所有课时。


项目定位

维度说明
目标1 个月内掌握 Compose 基础,具备独立写页面、接 ViewModel、做导航的能力
受众有 Android 开发经验、熟悉 Kotlin 基础、想系统入门 Compose
风格动手优先、XML 对照、渐进扩展(参考郭霖 Compose 教程 + 《第一行代码》0→1 路线)
工程参考Now in Android 的分层与工程化思路

双轨架构:可运行代码 + 课节资料库

项目采用 「App 练手 + lessons 归档」 双轨设计,这是理解整个仓库的关键:

compose-learning/
├── app/                                    # 轨道一:可编译运行的 Android 工程
│   └── src/main/java/.../
│       ├── MainActivity.kt                 # 应用入口:课节导航首页
│       ├── lesson01/                       # 第 1 课代码包(后续 lesson02/、lesson03/…)
│       │   ├── Lesson01Activity.kt         # 第 1 课独立 Activity 入口
│       │   └── ProfileCard.kt              # 第 1 课作业成果
│       └── ui/theme/                       # Material3 主题
│
├── lessons/                                # 轨道二:脱离 IDE 可读的课节资料库
│   ├── README.md                           # 课节总索引
│   └── lesson-01-setContent-composable/    # 第 1 课归档(下文详述)
│       ├── README.md                       # 课节元信息 + 资料导航
│       ├── notes.md                        # 系统复习笔记
│       ├── demo/                           # 代码归档副本
│       ├── homework.md                     # 作业题目与验收标准
│       ├── review.md                       # 批改记录
│       └── deep-dive.md                    # 深度拓展(可选)
│
└── .cursor/skills/                         # 可选:Cursor AI 学习辅导技能
    ├── compose-learning-coach/             # 课节教练:建夹、Demo、作业、归档
    └── compose-learning-tutor/             # 改代码后自动 XML 对照讲解

设计原则:

原则说明
一课一包每课代码放在 lesson{NN}/ 包下,入口为 Lesson{NN}Activity,互不干扰
导航首页MainActivityLazyColumn 展示课节列表,数据驱动(lessonHubItems),课节增多可滚动
资料同步lessons/lesson-{NN}-xxx/app/lesson{NN}/ 保持同步,方便 Git 复习
渐进合入各课 Demo 与作业逐步汇入同一 App,形成贯穿式练手项目

后续每增加一课,复制这套结构:lesson02/ + lessons/lesson-02-xxx/,并在 MainActivity 中同步完成三件事:

  1. lessonHubItems 列表追加一条课节数据
  2. onLessonClickwhen 分支增加 Intent 跳转
  3. AndroidManifest.xml 注册 Lesson{NN}Activity

标准课节流程(每课通用)

无论第几课,都按同一个五步流程推进,资料同步落盘到 lessons/ 目录:

Step A  Demo 演示      →  先跑通最小可运行示例 + Preview
Step B  知识点普及    →  对照 Demo 讲,XML 概念一一映射
Step C  作业布置      →  1~2 道必做,要求手写提交
Step D  作业 Review   →  对照 checklist 批改,写入 review.md
Step E  深度拓展      →  官方文档 / Now in Android 对照(可选,写入 deep-dive.md)

禁止跳步: 不先给 Demo 就长篇讲理论;一次课不超过 2 道必做作业。


以第 1 课为例:setContent 与 Composable 入门

下面用第 1 课完整走一遍上述流程,帮你理解「跟这个仓库学一课」到底是什么体验。

本课目标

理解 Compose 的入口 setContent、学会编写与组合 @Composable 函数,能用 Column + Text + Modifier 搭建简单页面,并通过 @Preview 在 IDE 中预览界面。

应用入口:课节导航首页

启动 App 后,首先进入 MainActivity 的课节列表。列表使用 LazyColumn + 数据驱动,课节增多时可纵向滚动,不会一屏展示不下:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            ComposeLearningTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    LessonHubScreen(
                        modifier = Modifier.padding(innerPadding),
                        onLessonClick = { lessonNumber ->
                            when (lessonNumber) {
                                1 -> startActivity(Intent(this, Lesson01Activity::class.java))
                                // 后续课时在此追加 when 分支
                            }
                        },
                    )
                }
            }
        }
    }
}

课节数据集中维护,新增课时只需往列表追加一条:

private data class LessonHubItem(
    val number: Int,
    val title: String,
    val description: String,
)

private val lessonHubItems = listOf(
    LessonHubItem(
        number = 1,
        title = "setContent 与 Composable 入门",
        description = "欢迎头部 · 学习名片 · 问候语",
    ),
    // 第 2 课、第 3 课…在此追加
)

LessonHubScreenLazyColumn 渲染标题区与课节卡片,点击后跳转到对应 LessonNNActivity

@Composable
fun LessonHubScreen(onLessonClick: (Int) -> Unit, modifier: Modifier = Modifier) {
    LazyColumn(
        modifier = modifier.fillMaxSize().padding(horizontal = 16.dp),
        verticalArrangement = Arrangement.spacedBy(12.dp),
    ) {
        item {
            Text("ComposeLearning", style = MaterialTheme.typography.headlineMedium)
            Text("选择课节开始学习", ...)
        }
        items(items = lessonHubItems, key = { it.number }) { lesson ->
            LessonEntryCard(
                lessonNumber = lesson.number,
                title = lesson.title,
                description = lesson.description,
                onClick = { onLessonClick(lesson.number) },
            )
        }
    }
}

这和 XML 时代「首页 RecyclerView → 详情 Activity」的模式一脉相承,只是列表本身也用 Compose 写了。

第 1 课入口:独立 Activity

每课有独立 Activity,便于隔离、复习和开源展示:

class Lesson01Activity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        setContent {
            ComposeLearningTheme {
                Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
                    Lesson01Screen(modifier = Modifier.padding(innerPadding))
                }
            }
        }
    }
}

界面组合:Composable 搭积木

第 1 课主界面由三个 Composable 纵向组合而成:

Lesson01Screen
├── WelcomeHeader(title, subtitle)   ← Demo 演示
├── ProfileCard                        ← 作业成果
└── Greeting(name, lessonNumber)     ← Demo + 作业微调
@Composable
fun Lesson01Screen(modifier: Modifier = Modifier) {
    Column(modifier = modifier) {
        WelcomeHeader(
            title = "wzj",
            subtitle = "Compose 学习者",
        )
        ProfileCard(
            modifier = Modifier.padding(top = 16.dp),
        )
        Greeting(
            name = "Android",
            lessonNumber = 1,
            modifier = Modifier.padding(top = 16.dp),
        )
    }
}

本课三个核心概念

第 1 课不堆 API,只搞懂三件事:

#概念XML 对照一句话
1setContent { }setContentView(R.layout.xxx)Activity 与 Compose 的桥梁,花括号内写 Composable
2@Composable布局 XML 里的 View 树用 Kotlin 函数声明 UI,可像积木一样组合
3@PreviewLayout Editor 预览不用装包到真机,IDE 里直接看效果

XML → Compose 对照表(第 1 课范围)

XML / ViewCompose说明
AppCompatActivityComponentActivityCompose 专用 Activity 基类
setContentView(R.layout.xxx)setContent { }入口换成 Composable
LinearLayout(vertical)Column纵向排列
LinearLayout(horizontal)Row横向排列
TextViewText文本
android:paddingModifier.padding()内边距
match_parentModifier.fillMaxSize()填满父布局
wrap_content默认尺寸 / wrapContentSize()包裹内容
android:themeComposeLearningTheme { }应用主题
Layout Preview@Preview预览 Composable
CoordinatorLayout + 内容区Scaffold页面骨架,处理系统栏内边距
RecyclerView(竖向列表)LazyColumn可滚动列表,课节导航首页
ScrollView + LinearLayoutColumn + verticalScroll少量固定内容的滚动(课节少时也可用)

作业示例:学习名片 ProfileCard

第 1 课布置了两道必做作业,这里展示必做 1 的题目与验收标准(完整题目见 lessons/lesson-01-setContent-composable/homework.md):

题目:仿照 Demo 中的 WelcomeHeader,独立编写 ProfileCard Composable,展示学习名片信息。

要求摘要

  1. Column 纵向排列至少 3 行 Text(昵称、学习目标、当前课次)
  2. 暴露 modifier: Modifier = Modifier 参数,供外部控制间距
  3. MaterialTheme.typography 区分标题与正文
  4. 正文颜色用 MaterialTheme.colorScheme.onSurfaceVariant
  5. 编写 @Preview 预览函数

作业成果代码:

@Composable
fun ProfileCard(modifier: Modifier = Modifier) {
    Column(modifier = modifier) {
        Text(
            text = "昵称:wzj",
            style = MaterialTheme.typography.titleMedium,
        )
        Text(
            text = "学习目标:1 个月掌握 Compose",
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
        )
        Text(
            text = "当前课次:第 1 课",
            style = MaterialTheme.typography.bodyMedium,
            color = MaterialTheme.colorScheme.onSurfaceVariant,
        )
    }
}

必做 2 则是微调 GreetingnamelessonNumber 参数——体会 Composable 参数化的思想:同一个函数,传入不同参数就能复用。

第 1 课资料归档一览

课时完成后,lessons/lesson-01-setContent-composable/ 下的资料结构如下,后续每一课都按同样格式归档

文件内容对应步骤
README.md本课目标、资料导航、Composable 结构图元信息
notes.md系统复习笔记(400+ 行,可脱离 IDE 阅读)Step B + 归档
demo/Lesson01Activity.ktProfileCard.kt 归档副本Step A
homework.md作业题目、验收标准、提交格式Step C
review.md批改结论、做得好的地方、改进建议Step D
deep-dive.md深度拓展(可选)Step E

想快速了解某课学了什么,看 lessons/lesson-{NN}-xxx/README.md;想系统复习,看 notes.md;想对照代码,看 demo/app/lesson{NN}/


完整学习路线

仓库按 6 个阶段规划,第 1 课属于「阶段 1 · 基础语法」的起点。后续每课都会按上文范式归档,此处列出全局路线图供参考:

阶段0 前置        → Kotlin 协程、环境搭建
阶段1 基础语法    → Column/Row/Modifier/LazyColumn(第 1 课起点)
阶段2 状态与架构  → remember、ViewModel、StateFlow、UDF
阶段3 进阶 UI     → Navigation、Dialog、Side Effect
阶段4 综合实战    → 迷你电商 / 列表+详情完整路径
阶段5 接入老项目  → ComposeView 嵌入、渐进式迁移

任务清单

任务内容验收标准
任务 1个人名片页Column + Text + Modifier + Preview
任务 2设置页列表LazyColumn + Switch + Divider
任务 3简单表单TextField + 状态展示
任务 4Todo AppViewModel + StateFlow + 四态 UI
任务 5分页列表下拉刷新 + 加载更多
任务 6两页导航Navigation Compose
任务 7弹窗场景Dialog / BottomSheet

入门合格线(7 项自检)

  • 不用 XML 独立完成 3 页 App
  • 会用 LazyColumn + ViewModel + StateFlow
  • 会用 Navigation Compose
  • 理解重组、remember、Side Effect
  • 能在 Activity 里嵌入 ComposeView
  • 能桥接 LiveData 与 Compose
  • 选一个真实模块做 POC 并评估迁移成本

快速上手

环境要求

  • Android Studio Hedgehog(2023.1.1)或更高
  • JDK 8+
  • compileSdk = 34minSdk = 24

克隆与运行

git clone https://gitee.com/wzj1157362131/compose-learning.git
  1. 用 Android Studio 打开项目
  2. 等待 Gradle Sync 完成
  3. 连接真机或启动模拟器,点击 Run
  4. 进入课节列表 → 点击「第 1 课」查看 Demo 与作业成果
  5. 也可直接打开 lesson01/Lesson01Activity.ktProfileCard.kt,使用 @Preview 预览

技术栈

  • Kotlin + Jetpack Compose(Material3)
  • Compose BOM 统一版本管理
  • Activity Compose + enableEdgeToEdge()
  • 后续课时逐步引入:ViewModel、Navigation、StateFlow 等

建议的学习顺序

  1. 克隆仓库,跑通 App,在课节列表中点击「第 1 课」查看效果
  2. 阅读 lessons/lesson-01-setContent-composable/notes.md 系统笔记
  3. 对照 app/lesson01/MainActivity.kt 源码,理解 Composable 组合与课节导航
  4. 自己重做 homework.md 里的作业(即使仓库已有答案,手写一遍收获最大)
  5. 查看 review.md 了解批改标准
  6. 按同样流程学习后续课时更第 2 课、第 3 课……

用 Cursor 的同学

仓库附带两套 Cursor Agent Skill,可作为「AI 助教」复用:

Skill作用
compose-learning-coach按课节流程带学;开始新课时同步创建 lesson{NN}/Lesson{NN}Activitylessons/lesson-{NN}-xxx/ 归档夹;作业与笔记自动落盘
compose-learning-tutor每次改 Compose 代码后,自动输出 XML 对照讲解(「📚 Compose 小课堂」)

不用 Cursor 也完全没问题——lessons/ 里的 notes.mdhomework.mddemo/ 可以独立阅读,不依赖任何 AI 工具。


参考资源

类型链接
官方 Compose 教程https://developer.android.com/jetpack/compose/tutorial
Composable 心智模型https://developer.android.com/jetpack/compose/mental-model
布局https://developer.android.com/jetpack/compose/layouts
状态管理https://developer.android.com/jetpack/compose/state
迁移指南https://developer.android.com/develop/ui/compose/migrate
郭霖 Compose 教程https://blog.csdn.net/guolin_blog/article/details/131622694
Now in Androidhttps://github.com/android/nowinandroid

写在最后

Compose 不是「替代 XML」这么简单,它背后是声明式 UI + 单向数据流的思维转变。有 XML 底子反而是优势——很多概念都能一一对照,学起来并没有想象中那么难。

ComposeLearning 的价值不在于某一课的 Demo 有多炫,而在于提供了一套可复用的学习范式

  • App 里能跑、能改、能 Preview
  • lessons/ 里能复习、能对照、能脱离 IDE 阅读
  • 每课流程固定,学到哪归档到哪,不会越学越乱

本文以第 1 课做了完整示范;如果你也在从 View 转 Compose,欢迎 Star、Fork,一起在 Issue 里交流。

仓库地址:
👉 https://gitee.com/wzj1157362131/compose-learning


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐