4. 基础按钮与点击事件

基础按钮与点击事件 学习卡片

Button 的最小可用结构

Compose 的 Button 是一个封装好的可点击容器:它内部组合了 Surface、Row 和 Text,并自动处理水波纹、最小触摸尺寸与无障碍语义。使用时只需要提供两个核心参数:onClick 回调与按钮内容。

@Composable
fun CounterButton() {
    var count by remember { mutableStateOf(0) }

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Text(text = "点击次数:$count", fontSize = 20.sp)
        Spacer(modifier = Modifier.height(16.dp))
        Button(onClick = { count++ }) {
            Text(text = "点我 +1")
        }
    }
}

关键点在于 count 使用 remember { mutableStateOf(0) } 保存。当 onClick 中执行 count++ 时,Compose 会读取到状态变化并重组 Text,界面上的数字随之刷新。若把 count 写成普通局部变量,点击后数值虽然改变,但不会触发重组,界面不会更新。

状态更新与重组链路

下面这张图展示了从手指按下到界面反馈的完整信号链:点击事件进入 onClick,修改 MutableState,Compose 侦测到读取该状态的可组合项并触发重组,最终 Text 用新值重新绘制。

用户点击 Button 触摸区域 onClick 回调 count++ MutableState count: 0 → 1 重组 Recomposition Text 重新读取 count 界面刷新:显示“点击次数:1” 状态驱动: onClick 只负责改状态,UI 由状态自动推导,无需手动查找控件并赋值。 重组范围: 只有读取了 count 的可组合项(此处为 Text)会被重新执行。

点击反馈的三种常见形态

“显示反馈”不一定只是数字变化。根据任务需要,可以在 onClick 中更新不同类型的状态,让界面给出不同层次的反馈:

  • 计数反馈:用 Int 状态记录点击次数,适合点赞、加购等场景。
  • 开关反馈:用 Boolean 状态切换文案或颜色,例如“已关注 / 关注”。
  • 瞬时反馈:点击后把状态置为 true,配合 LaunchedEffect 延时复位,实现“已复制”提示。
@Composable
fun ToggleFollowButton() {
    var followed by remember { mutableStateOf(false) }

    Button(onClick = { followed = !followed }) {
        Text(text = if (followed) "已关注" else "关注")
    }
}

这里 followed 同时决定按钮文案,点击后状态取反,按钮文字立即切换。注意状态必须定义在 Button 外部,否则每次重组都会重新初始化为 false,点击将看不到任何变化。

如果点击后界面没有更新,优先检查三件事:状态是否用 remember 保存、状态是否定义在会重组的可组合项作用域内、onClick 中是否真的修改了该状态。

可复用的点击反馈检查清单

检查项正确做法常见错误
状态声明var count by remember { mutableStateOf(0) }使用普通 var count = 0
状态位置放在 Button 外层的可组合项中写在 Button 的 lambda 内部
事件绑定Button(onClick = { count++ })忘记传 onClick 或写成空 lambda
反馈呈现Text 读取状态并显示只改状态但界面没有读取它