Media Player进度条实现问题:Jetpack Compose Slider适配与拖动跳转
Jetpack Compose 中 MediaPlayer 与 Slider 适配方案
解决进度精度问题
MediaPlayer 的 duration 和 currentPosition 都是毫秒级的 Int 类型,Slider 则要求 0f 到 1f 的浮点范围。要实现100%精准的进度映射,只需将当前播放位置除以总时长,得到0到1之间的浮点值即可:
- 计算当前进度:
currentPosition.toFloat() / duration.toFloat() - 必须先判断
duration > 0,避免出现除以0的异常
实现滑块拖动跳转播放位置
通过 Slider 的回调方法将滑块值转换回毫秒数,调用 MediaPlayer.seekTo() 完成跳转:
- 在
onValueChangeFinished中执行跳转(避免拖动过程中频繁调用seek,影响播放性能) - 转换公式:
(sliderValue * duration).toInt()
完整代码示例
@Composable fun AudioPlayerSlider(mediaPlayer: MediaPlayer) { val currentProgress = remember { mutableStateOf(0f) } val duration = mediaPlayer.duration.toFloat() // 实时更新播放进度 LaunchedEffect(mediaPlayer.isPlaying) { while (mediaPlayer.isPlaying) { if (duration > 0) { currentProgress.value = mediaPlayer.currentPosition.toFloat() / duration } delay(100) // 每100ms更新一次,平衡性能与流畅度 } } Slider( value = currentProgress.value, onValueChange = { newValue -> currentProgress.value = newValue }, onValueChangeFinished = { if (duration > 0) { val targetPosition = (currentProgress.value * duration).toInt() mediaPlayer.seekTo(targetPosition) } }, valueRange = 0f..1f ) }
关键细节说明
- 用
LaunchedEffect监听播放状态,仅在播放时循环更新进度,避免无效UI刷新 - 限制进度更新频率为100ms,减少不必要的重绘次数
- 在
onValueChangeFinished中执行跳转,避免拖动过程中频繁调用seekTo导致的播放卡顿 - 始终判断
duration > 0,处理MediaPlayer未加载完成的初始状态
内容的提问来源于stack exchange,提问作者bovietvidai
相关产品推荐
相关产品推荐

