🎒 中小学生色系课堂
在 Jetpack Compose 中,点击是最基础也最强大的手势。我们深入 Modifier.clickable 的回调机制,
并理清它与底层 Modifier.pointerInput 的适用边界。
Modifier.clickable 是 Compose 为通用点击场景提供的高级抽象。它封装了按下、抬起、视觉反馈(涟漪)、无障碍等行为。
// 最简单的点击 —— 自带波纹与无障碍
Box(
modifier = Modifier
.size(120.dp)
.background(Color(0xFFFAD7A0))
.clickable {
// onClick 回调
println("📣 按钮被点击")
}
) {
Text("点我", modifier = Modifier.align(Alignment.Center))
}
只需一个 lambda,Compose 自动处理触摸消抖、视觉反馈、无障碍事件。适合 80% 的点击场景。
clickable 不止一个 lambda,还支持 interactionSource、indication、enabled 等。
| 参数 | 类型 | 说明 | 学生色系示例 |
|---|---|---|---|
| onClick | () -> Unit | 点击回调,核心事件 | lambda |
| enabled | Boolean | 是否响应点击,false 时禁用视觉与回调 | 灰化 |
| interactionSource | MutableInteractionSource | 收集按压/拖拽等交互状态,可自定义涟漪 | ⭐ 常用 |
| indication | Indication? | 视觉反馈(涟漪/高亮),null 取消效果 | 无波纹 |
// 定制 enabled 与 interactionSource
val interactionSource = remember { MutableInteractionSource() }
Box(
modifier = Modifier
.size(140.dp, 60.dp)
.background(if (enabled) Color(0xFFB5D3E8) else Color.LightGray)
.clickable(
enabled = enabled,
interactionSource = interactionSource,
indication = rememberRipple(bounded = true)
) {
println("✅ 可点击状态: $enabled")
}
) {
Text("开关点击", modifier = Modifier.align(Alignment.Center))
}
Modifier.pointerInput 是 Compose 底层手势原始 API,而 clickable 基于它构建,但提供了更高层的封装。
| 对比维度 | ✅ Modifier.clickable | ⚡ Modifier.pointerInput |
|---|---|---|
| 抽象层级 | 高级语义,开箱即用 | 原始事件流 (原始指针) |
| 事件粒度 | 封装为 onClick,忽略细节 | 可监听 Down / Move / Up / 取消 |
| 视觉反馈 | 内置 Indication (涟漪) | 无,需自行实现 |
| 无障碍 | 自动生成语义点击 | 需手动添加 semantics |
| 防抖 / 双击 | 内置防连点 (约 300ms) | 需自行控制 |
| 适用场景 | 按钮、卡片、列表项等通用点击 | 自定义手势 (长按、拖拽、双击、多点) |
左:clickable | 右:pointerInput 实现相同点击效果
// clickable 一行搞定
Box(
modifier = Modifier
.size(100.dp)
.background(Color(0xFFFAD7A0))
.clickable {
println("clickable 点击")
}
)
// pointerInput 原始实现
Box(
modifier = Modifier
.size(100.dp)
.background(Color(0xFFFAD7A0))
.pointerInput(Unit) {
detectTapGestures(
onTap = {
println("pointerInput 点击")
}
)
}
)
detectTapGestures 是 pointerInput 的辅助函数,但依然缺少涟漪与无障碍。若完全手写原始指针,代码更长。
⬆️ 从 clickable 到原始 pointerInput,抽象层级逐渐降低,灵活性升高
clickable(interactionSource, indication) 替换涟漪。pointerInput + detectTapGestures 或 detectDragGestures。awaitPointerEventScope 处理 Down/Move/Up。.semantics { onClick }。