如何实现MP音频播放至3秒高亮TextView、5秒取消高亮?
解决音频播放时TextView定时高亮的问题
嘿,我明白你要实现的效果:音频刚启动时文字正常,播放到第3秒让TextView高亮,到第5秒再恢复原色。你的现有代码只处理了音频的初始化和播放触发,完全没对播放进度做监听,自然没法在指定时间点更新UI。下面给你具体的解决方案:
核心思路
要实现定时UI更新,我们需要在音频播放过程中,周期性检查当前播放位置,当到达3秒、5秒这两个时间节点时,修改TextView的颜色。Android的MediaPlayer本身没有直接的进度回调,所以我们可以用Handler来实现一个简单的进度检查器。
修正后的完整代码示例
先贴出可直接复用的代码,我会逐段解释关键部分:
// 先定义类成员变量(避免局部变量被回收) private MediaPlayer mp; private Handler mProgressHandler = new Handler(Looper.getMainLooper()); private TextView p5_1_a; private Runnable progressChecker; // 你的TextView点击事件处理逻辑 p5_1_a.setOnClickListener(v -> { // 如果音频正在播放,先停止并清理资源 if (mp != null && mp.isPlaying()) { mp.stop(); mp.release(); mp = null; mProgressHandler.removeCallbacks(progressChecker); p5_1_a.setTextColor(Color.BLACK); // 立即恢复原色 return; } try { mp = new MediaPlayer(); AssetFileDescriptor afd = getActivity().getAssets().openFd("q1p6_1.mp3"); mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); // 异步准备音频,避免阻塞UI线程 mp.prepareAsync(); // 音频准备完成后开始播放,并启动进度检查 mp.setOnPreparedListener(mediaPlayer -> { mediaPlayer.start(); // 初始化进度检查任务 progressChecker = new Runnable() { @Override public void run() { if (mp == null || !mp.isPlaying()) return; int currentMs = mp.getCurrentPosition(); // 获取当前播放位置(毫秒) if (currentMs >= 3000 && currentMs < 5000) { // 播放到第3秒,设置高亮颜色 p5_1_a.setTextColor(Color.parseColor("#FF4081")); // 替换成你要的高亮色 } else if (currentMs >= 5000) { // 播放到第5秒,恢复默认颜色 p5_1_a.setTextColor(Color.BLACK); // 到达5秒后可以停止检查,节省资源 mProgressHandler.removeCallbacks(this); } // 每隔100毫秒检查一次,保证精度 mProgressHandler.postDelayed(this, 100); } }; // 启动进度检查 mProgressHandler.post(progressChecker); }); // 监听音频播放结束,清理资源并恢复UI mp.setOnCompletionListener(mediaPlayer -> { p5_1_a.setTextColor(Color.BLACK); mProgressHandler.removeCallbacks(progressChecker); mediaPlayer.release(); mp = null; }); } catch (IOException e) { e.printStackTrace(); // 这里可以加个Toast提示用户播放失败 Toast.makeText(getActivity(), "音频播放失败", Toast.LENGTH_SHORT).show(); } });
关键细节解释
- 异步准备音频:用
prepareAsync()替代同步的prepare(),避免在主线程阻塞导致ANR(应用无响应)。 - 进度检查Runnable:通过Handler每隔100毫秒检查一次当前播放位置,判断是否到达目标时间点。这个间隔可以根据需求调整,越小精度越高,但不要太频繁(比如小于50ms),避免占用过多资源。
- UI更新安全:因为
mProgressHandler是用主线程Looper创建的,所以在Runnable里修改TextView颜色的操作是安全的,不需要额外切换线程。 - 资源清理:在音频停止、播放结束或重新点击时,一定要移除Handler的回调并释放MediaPlayer资源,否则会导致内存泄漏。
额外提示
- 如果需要支持音频暂停/继续,记得在暂停时调用
mProgressHandler.removeCallbacks(progressChecker),继续时重新调用mProgressHandler.post(progressChecker)。 - 高亮颜色可以换成你项目里的资源色,比如
getResources().getColor(R.color.highlight_color)(注意API版本适配)。 - 确保
p5_1_a已经通过findViewById或ViewBinding正确初始化,避免空指针异常。
这样修改后,就能完美实现你想要的定时高亮效果啦!
内容的提问来源于stack exchange,提问作者Fahad Jameel
相关产品推荐
相关产品推荐

