You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose中如何用onPressIn、onPressOut实现按住录音松开停止功能

Jetpack Compose 按住录音按钮实现方案

要实现按下启动录音、松开停止录音的交互,我们需要替换默认的Button点击监听,改用可以捕获按下、松开事件的修饰符处理,具体实现步骤如下:

前置注意事项

  • 提前申请Android录音权限RECORD_AUDIO,运行时未授权的情况下调用录音逻辑会触发崩溃
  • 如果使用combinedClickable需要添加@OptIn(ExperimentalFoundationApi::class)注解,该API在Compose 1.4+版本已稳定

完整实现代码

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color

@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Screen() {
    // 录音状态,可用于同步UI展示和业务逻辑判断
    var isRecording by remember { mutableStateOf(false) }
    val interactionSource = remember { MutableInteractionSource() }

    Button(
        onClick = { /* 无需处理默认点击逻辑 */ },
        // 根据录音状态修改按钮样式,给用户明确的状态反馈
        colors = ButtonDefaults.buttonColors(
            containerColor = if (isRecording) Color.Red else Color(0xFF2196F3)
        ),
        modifier = Modifier
            .combinedClickable(
                interactionSource = interactionSource,
                indication = null, // 不需要默认点击涟漪效果可保留,否则删除该行
                onPress = {
                    // 按下触发:执行启动录音逻辑
                    startRecording()
                    isRecording = true
                    // 挂起等待用户松开手指,即使用户滑出按钮区域再松开也能被捕获
                    tryAwaitRelease()
                    // 松开触发:执行停止录音逻辑
                    stopRecording()
                    isRecording = false
                }
            )
    ) {
        Text(
            text = if (isRecording) "录音中,松开结束" else "按住录音",
            color = Color.White
        )
    }
}

// 自行实现录音启动逻辑,可使用MediaRecorder或AudioRecord实现
private fun startRecording() {
    // 初始化录音实例、配置参数、启动录音
}

// 自行实现录音停止逻辑
private fun stopRecording() {
    // 停止录音、释放资源、存储录音文件
}

替代实现方案(不用combinedClickable)

如果不想使用实验性API(Compose 1.4以下版本),可以用pointerInput的detectTapGestures实现相同效果,修饰符替换为以下代码即可:

Modifier.pointerInput(Unit) {
    detectTapGestures(
        onPress = {
            startRecording()
            isRecording = true
            tryAwaitRelease()
            stopRecording()
            isRecording = false
        }
    )
}

可选扩展能力

如果需要实现滑动取消录音的交互,可以在tryAwaitRelease()之前添加位置判断逻辑:

  • 监听手指滑动位置,当手指移出按钮范围超过阈值时,提前停止录音并标记为取消
  • 可以配合状态展示“松开取消”的提示文字

内容的提问来源于stack exchange,提问作者Omar Khaled

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 11:00:02