仓库地址: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,互不干扰 |
| 导航首页 | MainActivity用LazyColumn展示课节列表,数据驱动(lessonHubItems),课节增多可滚动 |
| 资料同步 | lessons/lesson-{NN}-xxx/与app/lesson{NN}/保持同步,方便 Git 复习 |
| 渐进合入 | 各课 Demo 与作业逐步汇入同一 App,形成贯穿式练手项目 |
后续每增加一课,复制这套结构:lesson02/+lessons/lesson-02-xxx/,并在MainActivity中同步完成三件事:
lessonHubItems列表追加一条课节数据onLessonClick的when分支增加Intent跳转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+ 数据驱动,课节增多时可纵向滚动,不会一屏展示不下:
classMainActivity:ComponentActivity(){overridefunonCreate(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 分支}},)}}}}}课节数据集中维护,新增课时只需往列表追加一条:
privatedataclassLessonHubItem(valnumber:Int,valtitle:String,valdescription:String,)privatevallessonHubItems=listOf(LessonHubItem(number=1,title="setContent 与 Composable 入门",description="欢迎头部 · 学习名片 · 问候语",),// 第 2 课、第 3 课…在此追加)LessonHubScreen用LazyColumn渲染标题区与课节卡片,点击后跳转到对应LessonNNActivity:
@ComposablefunLessonHubScreen(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,便于隔离、复习和开源展示:
classLesson01Activity:ComponentActivity(){overridefunonCreate(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 + 作业微调@ComposablefunLesson01Screen(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 对照 | 一句话 |
|---|---|---|---|
| 1 | setContent { } | setContentView(R.layout.xxx) | Activity 与 Compose 的桥梁,花括号内写 Composable |
| 2 | @Composable | 布局 XML 里的 View 树 | 用 Kotlin 函数声明UI,可像积木一样组合 |
| 3 | @Preview | Layout Editor 预览 | 不用装包到真机,IDE 里直接看效果 |
XML → Compose 对照表(第 1 课范围)
| XML / View | Compose | 说明 |
|---|---|---|
AppCompatActivity | ComponentActivity | Compose 专用 Activity 基类 |
setContentView(R.layout.xxx) | setContent { } | 入口换成 Composable |
LinearLayout(vertical) | Column | 纵向排列 |
LinearLayout(horizontal) | Row | 横向排列 |
TextView | Text | 文本 |
android:padding | Modifier.padding() | 内边距 |
match_parent | Modifier.fillMaxSize() | 填满父布局 |
wrap_content | 默认尺寸 /wrapContentSize() | 包裹内容 |
android:theme | ComposeLearningTheme { } | 应用主题 |
| Layout Preview | @Preview | 预览 Composable |
CoordinatorLayout+ 内容区 | Scaffold | 页面骨架,处理系统栏内边距 |
RecyclerView(竖向列表) | LazyColumn | 可滚动列表,课节导航首页 |
ScrollView+LinearLayout | Column+verticalScroll | 少量固定内容的滚动(课节少时也可用) |
作业示例:学习名片 ProfileCard
第 1 课布置了两道必做作业,这里展示必做 1 的题目与验收标准(完整题目见lessons/lesson-01-setContent-composable/homework.md):
题目:仿照 Demo 中的WelcomeHeader,独立编写ProfileCardComposable,展示学习名片信息。
要求摘要:
Column纵向排列至少 3 行Text(昵称、学习目标、当前课次)- 暴露
modifier: Modifier = Modifier参数,供外部控制间距 - 用
MaterialTheme.typography区分标题与正文 - 正文颜色用
MaterialTheme.colorScheme.onSurfaceVariant - 编写
@Preview预览函数
作业成果代码:
@ComposablefunProfileCard(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则是微调Greeting的name和lessonNumber参数——体会 Composable参数化的思想:同一个函数,传入不同参数就能复用。
第 1 课资料归档一览
课时完成后,lessons/lesson-01-setContent-composable/下的资料结构如下,后续每一课都按同样格式归档:
| 文件 | 内容 | 对应步骤 |
|---|---|---|
README.md | 本课目标、资料导航、Composable 结构图 | 元信息 |
notes.md | 系统复习笔记(400+ 行,可脱离 IDE 阅读) | Step B + 归档 |
demo/ | Lesson01Activity.kt、ProfileCard.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 + 状态展示 |
| 任务 4 | Todo App | ViewModel + 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 = 34,minSdk = 24
克隆与运行
gitclone https://gitee.com/wzj1157362131/compose-learning.git- 用 Android Studio 打开项目
- 等待 Gradle Sync 完成
- 连接真机或启动模拟器,点击 Run
- 进入课节列表 → 点击「第 1 课」查看 Demo 与作业成果
- 也可直接打开
lesson01/Lesson01Activity.kt或ProfileCard.kt,使用@Preview预览
技术栈
- Kotlin+Jetpack Compose(Material3)
- Compose BOM统一版本管理
- Activity Compose+
enableEdgeToEdge() - 后续课时逐步引入:ViewModel、Navigation、StateFlow 等
建议的学习顺序
- 克隆仓库,跑通 App,在课节列表中点击「第 1 课」查看效果
- 阅读
lessons/lesson-01-setContent-composable/notes.md系统笔记 - 对照
app/lesson01/与MainActivity.kt源码,理解 Composable 组合与课节导航 - 自己重做
homework.md里的作业(即使仓库已有答案,手写一遍收获最大) - 查看
review.md了解批改标准 - 按同样流程学习后续课时更第 2 课、第 3 课……
用 Cursor 的同学
仓库附带两套 Cursor Agent Skill,可作为「AI 助教」复用:
| Skill | 作用 |
|---|---|
compose-learning-coach | 按课节流程带学;开始新课时同步创建lesson{NN}/Lesson{NN}Activity与lessons/lesson-{NN}-xxx/归档夹;作业与笔记自动落盘 |
compose-learning-tutor | 每次改 Compose 代码后,自动输出 XML 对照讲解(「📚 Compose 小课堂」) |
不用 Cursor 也完全没问题——lessons/里的notes.md、homework.md、demo/可以独立阅读,不依赖任何 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 Android | https://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