kotlin:Jetpack Compose 给APP添加声音(点击音效/背景音乐)

Jetpack Compose 给APP添加声音(点击音效/背景音乐)

在 Jetpack Compose 中播放声音,最常用、最简单 的方案是使用 Android 原生的 SoundPool (短音效,如点击、弹窗)和 MediaPlayer(长音频,如背景音乐)。

我给你整理了开箱即用的完整代码,直接复制就能用。


第一步:准备音频文件

  1. res 目录下创建 raw 文件夹(右键 res → New → Android Resource Directory → Resource type 选 raw
  2. 把你的音频文件(mp3 / wav 格式)放进去,例如:
    • click_sound.wav
    • bg_music.mp3

文件名只能是:小写字母、数字、下划线


方案1:短音效(点击按钮/交互)SoundPool ✅

适合点击、弹窗、反馈等短音频,延迟低、性能好。

完整 Compose 代码

kotlin 复制代码
import android.media.SoundPool
import android.content.Context
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext

// 播放点击音效
@Composable
fun PlaySoundScreen() {
    val context = LocalContext.current

    // 1. 初始化 SoundPool
    val soundPool = remember {
        SoundPool.Builder()
            .setMaxStreams(1) // 同时播放的音频数量
            .build()
    }

    // 2. 加载音频(只加载一次)
    val clickSoundId = remember {
        soundPool.load(context, R.raw.click_sound, 1)
    }

    // 3. 页面销毁时释放资源
    DisposableEffect(Unit) {
        onDispose {
            soundPool.release()
        }
    }

    // 页面布局
    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Button(onClick = {
            // 播放音效:(soundID, 左音量, 右音量, 优先级, 循环, 播放速度)
            soundPool.play(clickSoundId, 1f, 1f, 1, 0, 1f)
        }) {
            Text("点击播放音效")
        }
    }
}

参数说明

  • 1f, 1f:左右音量(0.0 ~ 1.0)
  • 0:循环次数(0=不循环,-1=无限循环)
  • 1f:播放速度(0.5~2.0)

方案2:长音频(背景音乐)MediaPlayer ✅

适合背景音乐、语音播报等长音频。

完整 Compose 代码

kotlin 复制代码
import android.media.MediaPlayer
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext

// 播放背景音乐
@Composable
fun PlayBackgroundMusicScreen() {
    val context = LocalContext.current

    // 初始化 MediaPlayer
    val mediaPlayer = remember {
        MediaPlayer.create(context, R.raw.bg_music).apply {
            isLooping = true // 循环播放
            setVolume(0.5f, 0.5f) // 音量
        }
    }

    // 页面销毁时停止并释放
    DisposableEffect(Unit) {
        onDispose {
            mediaPlayer.stop()
            mediaPlayer.release()
        }
    }

    Column(
        modifier = Modifier.fillMaxSize(),
        horizontalAlignment = Alignment.CenterHorizontally,
        verticalArrangement = Arrangement.Center
    ) {
        Button(onClick = { mediaPlayer.start() }) {
            Text("播放背景音乐")
        }

        Button(onClick = { mediaPlayer.pause() }) {
            Text("暂停背景音乐")
        }
    }
}

方案3:全局点击音效(整个APP点击都发声)

如果你想所有按钮点击都自动播放音效 ,可以封装一个自定义点击修饰符

kotlin 复制代码
import androidx.compose.foundation.clickable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import android.media.SoundPool

// 全局带音效的点击
@Composable
fun Modifier.clickWithSound(
    soundId: Int,
    soundPool: SoundPool,
    onClick: () -> Unit
): Modifier {
    return this.clickable {
        soundPool.play(soundId, 1f, 1f, 1, 0, 1f)
        onClick()
    }
}

使用:

kotlin 复制代码
Text(
    text = "点我有声音",
    modifier = Modifier.clickWithSound(clickSoundId, soundPool) {
        // 你的点击逻辑
    }
)

常见问题

  1. 音频没声音?

    • 检查文件是否放在 res/raw/
    • 检查音量是否打开
    • 音频文件名必须小写
  2. 报错资源找不到?

    • 重建项目:Build → Clean Project → Rebuild Project
  3. 页面退出还在响?

    • 必须用 DisposableEffect 在页面销毁时 release() 释放音频

总结

  • 短音效(点击) :用 SoundPool,延迟低
  • 长音效(背景音乐) :用 MediaPlayer
  • 音频文件放在 res/raw/
  • 页面销毁必须释放资源,避免内存泄漏

需要我帮你把音效封装成一个工具类,让整个 APP 随便调用吗?

相关推荐
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.2 小时前
MySQL半同步复制与GTID实战详解
android·mysql·adb
吴声子夜歌2 小时前
ES6——对象的扩展详解
开发语言·javascript·es6
aq55356002 小时前
编程语言对比:从汇编到PHP的四大层级解析
开发语言·汇编·php
kyle~2 小时前
工程数学---Eigen库(C++唯一标配线性代数库)
开发语言·c++·线性代数
CoderCodingNo2 小时前
【GESP】C++五、六级练习题 luogu-P1886 【模板】单调队列 / 滑动窗口
开发语言·c++·算法
好家伙VCC2 小时前
**发散创新:基于Rust的轻量级权限管理库设计与开源许可证实践**在现代分布式系统中,**权限控制(RBAC
java·开发语言·python·rust·开源
xiaoshuaishuai83 小时前
C# 方言识别
开发语言·windows·c#
John.Lewis3 小时前
C++进阶(6)C++11(2)
开发语言·c++·笔记
@atweiwei3 小时前
用 Rust 构建agent的 LLM 应用的高性能框架
开发语言·后端·rust·langchain·eclipse·llm·agent