跳到正文ChatGPT 说 · Jimmy Huang's BlogChatGPT 说
本页目录· 43 条
1. 本周 Seminar 总览
这周 Seminar 的技术主线,其实只有一句话:Jetpack Compose 里的 UI 不是你手动一格一格去“更新”的,而是由 state(状态)驱动自动刷新。老师围绕这个核心,讲了 4 个东西:
Compose 为什么是 declarative UI(声明式 UI)
recomposition(重组) 是怎么发生的
state / MutableState 应该怎么声明、怎么更新
为什么做列表时要用 LazyColumn / mutableStateListOf,以及它们在 app 里为什么很常见。
这部分是本周最核心的技术内容。
老师口头解释比课件更重要的一点是:她一直在帮大家建立一个“脑子里的运行模型”。不是让你死记 API,而是让你明白:UI = 你当前状态的显示结果。状态一变,Compose 就会把受影响的部分重新画出来。你真正该学会的,不是“怎么强制刷新页面”,而是“哪些数据必须被声明成可观察的 state、怎么改 state 才会触发 UI 更新”。
另外,这周 seminar 还有一条很强的“隐形主线”:本周内容会直接服务后面的 assignment build。老师明确提到 lazy list 会用到、Assessment 2 要尽早考虑组队和项目方向、要学 Git/GitLab、要保留 AI 使用记录、Week 5 presentation 不能随便缺席。也就是说,这周不是只学理论,而是在给后面真正做 app 打地基。
2. 核心知识点总结
知识点 1:Jetpack Compose 是什么,为什么叫“声明式 UI”
是什么:
Jetpack Compose 是 Android 的声明式 UI 框架。你不是像旧式写法那样一步一步命令系统“先画这个、再改那个、最后 update”,而是直接描述“这个 UI 应该长什么样”。课件里说得很直接:Compose 会根据当前 UI state 重新调用 composable function 来更新界面
为什么重要:
因为这决定了你后面所有代码的思路。你如果还用“命令式”思维写 Compose,很容易写得很乱,或者不知道为什么 UI 没更新。
怎么理解:
老师用了一个很好的类比:
命令式(imperative):你教别人怎么做三明治——先放两片面包,再放培根,再放芝士。
声明式(declarative):你只说“我要一个三明治”,然后把要的配料传进去。
Compose 就像第二种:你告诉它“我想要什么 UI 效果”,而不是“每一步怎么画”。
学生更容易理解的话就是:你不是在亲手修屏幕,而是在改“数据”,让屏幕自己变。
这门课后面要做 Android app。你后续做页面、表单、列表、导航,都会基于这种思路。不会这个,后面会一直卡。
知识点 2:Recomposition 是什么
Recomposition 就是:当 state 变了,Compose 会把受影响的 UI 重新组合 / 重新绘制。 课件里强调 “any time a state is updated, a recomposition takes place”。
因为这是 Compose 自动更新 UI 的核心机制。你要明白:不是所有值变化都会刷新,只有被 Compose 观察到的 state 变化 才会触发 recomposition。
老师把它解释成“重做一次更新循环”,但不是傻傻整页重画,而是只更新需要更新的部分。
后面你写输入框、按钮、列表、筛选、导航,全部都在靠 recomposition 工作。quiz / exam 很可能会考你对这个机制的理解,而不是只考你背 API 名字。老师还明确提到 composition 三阶段“可能会在 quiz 里测试”。
知识点 3:Compose 不会自动观察所有数据,必须显式声明 state
课件明确说:Compose 不会自动观察变化,你必须自己声明哪些数据是要追踪的,常见做法就是用 mutableStateOf()。
这是很多初学者最容易踩坑的地方。你明明改了变量,为什么 UI 不动?
原因通常不是“Compose 坏了”,而是:你改的不是 observable state。
UI 是 state driven / value driven 的。
把会影响 UI 的数据声明成 state
改这个 state
让 Compose 自动更新 UI
学生更容易理解的话:不是“变量会不会变”最重要,而是“这个变量是不是被 Compose 当成 state 盯着看”。
这直接连接后面的表单、用户输入、下拉菜单、列表更新、页面状态保留。
知识点 4:MutableState、remember、以及 state 的声明方式
课件给了 3 种声明 MutableState 的方式,老师说前两种最常见,第二种更常用:
val name = remember { mutableStateOf("") }
var name by remember { mutableStateOf("") }
val (value, setValue) = remember { mutableStateOf(default) }
因为你后面几乎每个输入框、切换值、按钮结果显示,都会用到它。
remember:让这个值在 recomposition 之间保留下来。
mutableStateOf(...):把一个普通值包成 Compose 能观察的状态对象。
如果你用 Option 1,name 的类型其实不是 String,而是 MutableState<String>,所以你要写 name.value。
如果你用 Option 2,因为用了 by 代理,name 直接就像 String 一样用,不需要 .value。
老师专门强调:这就是很多人 confusion 的来源,而且她更推荐第二种,因为更自然、更不容易忘 .value。
这是 Compose 编程最常见的基本功,属于后面所有 app build 的底层写法。
知识点 5:it、lambda 简写、以及为什么这周会突然觉得语法变多
老师额外解释了 it:如果 lambda 只有一个参数,就可以用 it 作为简写。比如 onValueChange = { name = it }。
因为 Compose 代码里到处都是 lambda。你不懂 it,就会觉得代码像“天书”。
it 不是魔法,它只是“这个 lambda 唯一的那个参数”的默认名字。
学生更容易理解的话:别人没给这个输入起正式名字时,Kotlin 就临时叫它 it。
按钮点击、输入变化、列表 item 点击,这些都靠 lambda。
知识点 6:对象类型放进 mutableStateOf() 时,Compose 看的是“引用”不是“内部字段”
课件里专门用了 Student("Alice", 20) 的例子。student.name = "Bob" 不会触发 recomposition;要用 student = student.copy(name = "Bob") 才会更新 UI。
这是一个非常容易错、而且一错就很难看出来的问题。老师也明确说这类问题以前 lab 里很多学生会卡住。
Compose 盯的是“你手上拿的是不是同一个对象引用”。
你不是只给旧纸箱里面换了东西,而是换了一个新纸箱,系统才更容易发现变化。
以后你做数据模型、表单对象、用户信息、列表 item 状态时,都会遇到。
知识点 7:rememberSaveable、ViewModel、state hoisting
remember:在 recomposition 之间保留状态,但不能跨 configuration change。
rememberSaveable:可以在旋转屏幕、activity/process recreation 时把值保住。
ViewModel:也能持有 UI state,并能跨 configuration changes。
课件给了这三者关系,老师口头上则更偏向:在当前学习阶段更推荐先掌握 rememberSaveable;ViewModel 和 state hoisting 可以当扩展知识继续看。
因为你会遇到“我切屏 / 旋转后,刚输入的内容怎么没了?”
这是你后面 app 可用性和代码结构是否成熟的分水岭。
知识点 8:Lazy Lists(LazyColumn / LazyRow / mutableStateListOf)
因为真实 app 里的列表通常很多,而且后面还会接数据库。用普通 Column 去堆大量内容不合适。老师明确说 lazy list 在 app build 里会用到。
你可以把它理解成“懒加载的滚动列表”。用户没滚到的部分,先别急着都搬出来。
后面做数据库数据展示、联系人列表、商品列表、任务列表,都离不开它。
知识点 9:为什么列表更新要用 mutableStateListOf(),不是普通 listOf() / mutableListOf()
课件专门讲了 mutableStateListOf():它创建的是一个可观察的 MutableList。
如果你用的是普通 list,数据也许改了,但 UI 不一定更新。
这是后面 app 列表功能的必备能力,属于非常强的应用型知识点。
3. 老师强调的重点
重点 1:Compose 的核心不是“背组件”,而是理解 state-driven UI
老师整堂课都在反复围绕这个逻辑讲:declarative、recomposition、observable state、UI 自动更新,本质都在讲一个思路——你改的是 state,不是手动改视图。 她还用三明治类比讲了很久。
你必须掌握: UI 为什么会跟着 state 变。
重点 2:Composition / Layout / Drawing 三阶段,以及 Recomposition
老师明确说过这部分“可能会在 quiz 里测试”。这已经不是隐含重点,而是显性重点。
你必须掌握: 三阶段是什么;recomposition 为什么不是整页重绘。
重点 3:mutableStateOf() + remember
课件把它放在中心部分,老师也明确说这是“显式声明要观察的数据”的关键。
你必须掌握: 为什么普通变量不行,为什么 state holder 才能触发更新。
重点 4:Option 1 和 Option 2 的区别,尤其是 .value 和 by remember
老师口头上多次强调这是学生最容易混淆的地方,还说 “that’s super important and that’s where the confusion is coming from”。
重点 5:对象内部字段变化不一定触发 recomposition
老师不仅讲了,还专门提醒这类问题以前很多学生 lab 会出错。
你必须掌握: student.name = "Bob" 可能不更新;student = student.copy(...) 才会。
这很像 exam / assignment 常见坑点。
重点 6:列表必须用 mutableStateListOf()
老师明确把它和后面 app build 连接起来,并用国家列表示例讲新增 / 删除 / 选择。
重点 7:rememberSaveable 比只会 remember 更实用
老师专门解释了切屏、旋转、切换页面时数据丢失的问题,并明确推荐当前阶段优先掌握 rememberSaveable。
你必须掌握: “recomposition 之间保留” 和 “configuration change 之后也保留” 的区别。
重点 8:LazyColumn 很可能直接服务 assignment
老师直接说 lazy list 会在 app build 里用到,而且和以后数据库显示结合很紧。
LazyColumn 是什么
为什么比普通 Column 更适合长列表
为什么在手机端竖向列表更常见。
重点 9:本周不是只有技术,assignment 规则同样是高优先级
老师花了很多时间讲 A1 和 A2,这不是闲聊,而是在防止大家后面直接丢分。
Week 5 presentation 出勤必须重视
缺席会影响 individual mark;按老师口头说明,presentation component 中 group mark 60%,individual 40%
如果 review 的 paper 不是你们被分配/确认的 paper,会直接丢很重的 group 分(老师口头提到 50%)
AI 使用必须透明记录
A2 要尽早想组队、选题、学 Git。
4. transcript 里补充的重要信息
4.1 课件里没有展开,但老师讲得更好懂的地方
三明治类比:这是理解 declarative vs imperative 最好的口头补充。课件只有定义,老师把“写步骤”和“描述结果”区别讲得很清楚。
UI = state 的显示结果:老师不断把 Compose 讲成“value-driven / state-driven UI”。这比课件的文字定义更容易转成真正会写代码的理解。
recomposition 的触发源:老师补充说,用户交互是最常见触发源,但不是唯一来源,其他函数或连锁事件也可能改动 state。
Option 2 更推荐:课件只是给出写法,老师明确说第二种更常用,也更不容易被 .value 搞混。
primitive state 的优化类型:老师补充提到 integer / boolean 这种 primitive type 有更优化的 state 变体,不只是 generic MutableState<T>。这在课件里只轻轻带过,口头解释更具体。
LazyColumn 为什么更常见:课件只说 vertical / horizontal,老师把“手机更自然是上下滑”这个设计逻辑讲出来了。
grid 不是强制要求:课件列出 grid,但老师明确补充它不是当前 assignment 必做,只是你有需要可以用。
state hoisting / ViewModel 是扩展,不是今天的主战场:这能帮你分清“今天必须学会什么”和“今天先知道有这回事就行”。
4.2 老师给的学习建议 / 作业提醒
不要只停留在 lab 最基础的范围;想拿更好的结果,必须去看官方文档、做更多练习。
LazyColumn 相关更完整练习在 lab 4 notes 里。
A2 项目不要只做“to-do list / gym booking”这种太常见、太保守的题目,老师想看到更有意义、更有创造性的 app idea。
A2 要提交的是实际代码做出来的 skeleton 页面截图,不是只用 Figma / Canva 做得很漂亮的概念图
Git / GitLab 会是 A2/A4 的重要部分,老师要看成员贡献历史。
4.3 信息冲突 / 需要你注意的地方
我没有发现“实质性知识冲突”,但有两个地方需要你注意:
课件给的是全景图,老师口头给的是当前优先级。
例如课件提到 ViewModel、LiveData;老师口头上更推荐你当前阶段优先掌握 rememberSaveable,并把 state hoisting / ViewModel 当成延伸。这不是冲突,而是“先学什么、后学什么”的区别。
transcript 里有明显转写误差。
比如 composition 三阶段最后一项在 transcript 里一度像是 “join”,但结合老师语境和 Compose 语义,应理解为 drawing / rendering。所以遇到 transcript 看起来怪的术语,要优先用课件和上下文纠正。
5. 这周最可能要掌握的考点 / 作业相关点
A. 最像 quiz / exam 考点的内容
Declarative UI vs Imperative UI Composition 三阶段 + Recomposition remember { mutableStateOf(...) } 与 var by remember { ... } 的区别remember vs rememberSaveableLazyColumn vs Column、mutableStateListOf() 的作用
B. 最像 assignment / build 直接要用的内容
用 state 驱动 TextField、Button、Text 的联动
用 LazyColumn 做列表显示、选择、删除、添加
知道普通 list 不够,要用 mutableStateListOf()
知道切屏 / 重建时怎么保住状态
Assessment 2 项目要尽快确定队友、项目方向、Git 工作方式
A2 需要真正的 UI skeleton 页面,不是纯设计稿
AI 使用要留痕、要解释你怎么改过 AI 输出
A1 presentation 的提交和出勤规则不能出错
C. 隐含重点
这些老师不一定每一条都直接说“会考”,但很明显是高频重点:
6. 我应该怎么学这周内容
6.1 推荐学习顺序
先搞懂思维模型
先别急着背代码。先把这三件事想明白: 再学最常用语法
重点只学:remember
mutableStateOf
by remember
.value
rememberSaveable
最后把它映射到 assignment你的 app 哪些页面有输入框?
哪些地方有列表?
哪些状态需要旋转后保留?
哪些页面以后会接数据库?
6.2 你必须先搞懂的基础概念
6.3 哪些内容属于“理解型”
6.4 哪些内容属于“记忆型”
remember
mutableStateOf
rememberSaveable
mutableStateListOf
LazyColumn / LazyRow
Option 1 需要 .value
Option 2 用 by 不需要 .value
6.5 哪些内容属于“应用型”
TextField 的 value / onValueChange
点击 item 更新 selectedCountry
按钮新增 / 删除列表元素
用 copy 改 data class state
让状态在切屏后保留
6.6 哪些内容只需要了解
6.7 哪些内容需要重点掌握
6.8 这周最容易混淆的地方
普通变量 vs state
Option 1 vs Option 2
name 是 String 还是 MutableState
什么时候要 .value
it 到底是谁
改对象内部值为什么 UI 没动
普通 list / mutableListOf 和 mutableStateListOf 的区别
remember 和 rememberSaveable 的差别
6.9 学完后你应该能回答这些问题,才算真的掌握
为什么 Compose 叫 declarative UI?
为什么不是所有变量变化都会刷新 UI?
remember 和 rememberSaveable 差在哪?
为什么 var name by remember { mutableStateOf("") } 通常更好写?
为什么 name.value 有时必须写?
为什么 student.name = "Bob" 可能不更新画面?
为什么列表新增元素后 UI 没刷新时,要先检查是不是 mutableStateListOf()?
为什么手机里 LazyColumn 通常比 LazyRow 更常见?
你自己的 app 里,哪些数据应该做成 state?
7. 给我一份简短复习清单
本周快速 checklist
8. 如果我是初学者,你再用更简单的话解释一遍
你做 Android 页面时,不要再想“我要怎么手动把 화면改掉”,而要想“我现在的数据变成什么了”。
所以你写 Compose 时,核心不是“手动刷新”,而是:
把重要数据声明成 state
改这个 state
让 Compose 自己更新画面
如果你只是用普通变量,UI 可能不会跟着变
如果你用 mutableStateOf,UI 才知道要刷新
如果你怕旋转屏幕就丢数据,用 rememberSaveable
如果你做列表,不要傻傻用普通 Column 堆很多东西,要用 LazyColumn
如果你的列表会增删改,要用 mutableStateListOf()
如果你改的是一个对象里面的小字段,UI 不一定知道;有时要重新给它一个“新对象”
Compose 里,页面是“状态的结果”。你改状态,页面就跟着变。
而老师这周真正想让你做到的,不只是听懂定义,而是:
以后看到一个输入框,你知道它后面应该绑 state
看到一个列表,你知道要用 LazyColumn
列表新增删减不更新时,你知道去检查是不是 state list
做 assignment 的时候,你能把这些写进真正的 app 里,而不是只会看 slide。
补一个超短结论
Compose 是声明式 UI:你描述“要什么”,不是一步步写“怎么画”。
UI 由 state 驱动:state 变了,Compose 才会重组更新。
后面做 app 时,输入框、按钮、列表、页面状态保留,几乎都会直接用到这周内容。