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

如何实现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();
    }
});

关键细节解释

  1. 异步准备音频:用prepareAsync()替代同步的prepare(),避免在主线程阻塞导致ANR(应用无响应)。
  2. 进度检查Runnable:通过Handler每隔100毫秒检查一次当前播放位置,判断是否到达目标时间点。这个间隔可以根据需求调整,越小精度越高,但不要太频繁(比如小于50ms),避免占用过多资源。
  3. UI更新安全:因为mProgressHandler是用主线程Looper创建的,所以在Runnable里修改TextView颜色的操作是安全的,不需要额外切换线程。
  4. 资源清理:在音频停止、播放结束或重新点击时,一定要移除Handler的回调并释放MediaPlayer资源,否则会导致内存泄漏。

额外提示

  • 如果需要支持音频暂停/继续,记得在暂停时调用mProgressHandler.removeCallbacks(progressChecker),继续时重新调用mProgressHandler.post(progressChecker)。
  • 高亮颜色可以换成你项目里的资源色,比如getResources().getColor(R.color.highlight_color)(注意API版本适配)。
  • 确保p5_1_a已经通过findViewById或ViewBinding正确初始化,避免空指针异常。

这样修改后,就能完美实现你想要的定时高亮效果啦!

内容的提问来源于stack exchange,提问作者Fahad Jameel

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:24:04