前言
上一节课我们完成最简HelloWorld,认识了 @Composable 可组合函数、预览注解。
Compose声明式UI的核心:界面跟随状态自动更新。
本课重点学习状态定义、记忆状态、按钮点击事件,打通「状态‑重组‑界面刷新」完整闭环。
前置:完成第1课,Compose基础项目正常可编译预览
一、完整可运行示例源码
packagecom.example.composefirstimportandroid.os.Bundleimportandroidx.activity.ComponentActivityimportandroidx.activity.compose.setContentimportandroidx.compose.material3.Buttonimportandroidx.compose.material3.Textimportandroidx.compose.runtime.Composableimportandroidx.compose.runtime.getValueimportandroidx.compose.runtime.mutableIntStateOfimportandroidx.compose.runtime.rememberimportandroidx.compose.runtime.setValueimportandroidx.compose.ui.tooling.preview.PreviewclassMainActivity:ComponentActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContent{CounterPage()}}}@ComposablefunCounterPage(){// 定义记忆型状态varcountbyremember{mutableIntStateOf(0)}Text(text="当前计数:$count")Button(onClick={count+=1}){Text("点我+1")}}@Preview@ComposablefunCounterPreview(){CounterPage()}二、逐行代码解读
1. remember { … }
remember 是状态记忆函数。
可组合函数每次重组都会完整执行一遍,如果不套上 remember ,变量每次都会重置,无法保存上一次数值。
作用:在重组过程中保存数据,不会被反复初始化。
2. mutableIntStateOf(0)
生成可观察的整型状态对象,初始值0。
配套还有: mutableStateOf 通用任意类型、 mutableStringStateOf 字符串专用状态。
3. var count by
by 是 Kotlin 属性委托语法。
- 不加 by :你拿到的是状态对象 MutableIntState ,取值要写 .intValue ;
- 使用 by 委托:直接读写普通变量 count ,语法简洁。
导入提示
importandroidx.compose.runtime.getValueimportandroidx.compose.runtime.setValue缺少这两行导入, by 语法会直接报错。
4. Button(onClick = {})
按钮点击回调, onClick 是无参Lambda。
点击时修改状态变量 count +=1 。
5. 重组触发逻辑
count 属于被Compose监听的状态。一旦数值发生变更,Compose触发重组,重新运行 CounterPage ,界面上Text自动刷新出新数字。
关键点:
我们没有手动写刷新界面代码,状态变更自动驱动界面更新。
三、核心概念区分
- 普通局部变量
varcount=0每次重组重置,点击按钮界面不会变化,无法用于UI状态。
- remember + 状态对象
varcountbyremember{mutableIntStateOf(0)}remember留存变量;状态对象可被框架监听;修改状态触发重组,界面刷新。
易错点:
remember 只能放在 @Composable 函数内部,不能放在普通函数、全局作用域。
四、综合练习题
填空题
- 用来在重组期间保存数据的函数是________。
- 创建整型可监听状态的函数是________。
- Kotlin ________语法,可以省去 .intValue ,直接读写状态值。
答案与解析
- remember ;解析:没有remember,每次重组变量重置,状态丢失。
- mutableIntStateOf ;解析:专门用于整数状态,替代旧版 mutableStateOf(0) ,性能更好。
- 属性委托(by);解析:by 将取值赋值交给状态代理,简化代码。
判断题
- 去掉 remember,点击按钮,数值会自增但是界面不会更新。()
答案:错误。理由:没有remember,每次重组count重置为0,数值不会累加,界面不会有变化。
- onClick 回调内部可以直接修改 remember 包裹的状态变量。()
答案:正确。理由:修改可监听状态,会触发重组,自动刷新UI。
- remember 可以直接写在顶层全局位置。()
答案:错误。理由:remember 必须运行在可组合函数的Compose上下文,全局无法调用。
简答题
- 简述普通变量和 remember+状态变量最大区别?
参考答案:普通变量重组时重新初始化,数据无法留存,改动不会通知界面;remember 保存变量,状态对象被框架监听,修改后自动重组刷新页面。
- 代码实操题
修改示例代码:增加重置按钮,点击后 count 归零。写出完整 CounterPage 函数。参考答案
@ComposablefunCounterPage(){varcountbyremember{mutableIntStateOf(0)}Text(text="当前计数:$count")Button(onClick={count+=1}){Text("点我+1")}Button(onClick={count=0}){Text("重置")}}解析:新增第二个Button,点击回调把count赋值为0,状态变更触发界面刷新。
五、本课小结
- remember :跨重组保存数据;
- mutableXXStateOf :可被监听的状态;
- by 属性委托简化读写;
- 改变状态 → 自动重组 → UI更新,不需要手动刷新控件。
下一课:布局组件 Column、Row、Box,控制元素排列。