首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android 音樂播放器 SeekBar 拖動異常:未播放時禁用交互避免崩潰

     編輯:程式設計綜合問答

音樂播放器進度條在未播放狀態下拖動會報錯(如 NullPointerException 或 IllegalStateException),因 MediaPlayer 未初始化或未處於準備狀態,調用 seekTo() 導致異常。

解決方案:狀態驅動交互可用性

// 1. 定義播放狀態枚舉
enum PlayState { IDLE, PREPARING, PLAYING, PAUSED, COMPLETED, ERROR }
private PlayState currentState = PlayState.IDLE;

// 2. SeekBar 觸摸監聽中判斷狀態
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        if (currentState == PlayState.IDLE || currentState == PlayState.ERROR) {
            // 未播放或錯誤狀態,取消本次拖動
            Toast.makeText(ctx, "請先播放音樂", Toast.LENGTH_SHORT).show();
            // 關鍵:移除回調或標記忽略後續進度變更
            isUserSeeking = false; 
            return;
        }
        isUserSeeking = true; // 標記用戶正在拖動,暫停自動更新進度
        if (mediaPlayer != null) mediaPlayer.pause(); // 拖動時暫停播放
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        if (!fromUser || !isUserSeeking) return; // 非用戶操作或非拖動狀態忽略
        // 可選:實時顯示當前拖動時間
        tvCurrentTime.setText(formatTime(progress));
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        if (!isUserSeeking) return;
        isUserSeeking = false;
        if (mediaPlayer != null && currentState != PlayState.IDLE) {
            mediaPlayer.seekTo(seekBar.getProgress()); // 安全調用
            mediaPlayer.start(); // 恢復播放
        }
    }
});

// 3. 播放狀態變更時同步 SeekBar 狀態
private void updatePlayState(PlayState newState) {
    currentState = newState;
    boolean enabled = (newState == PlayState.PLAYING || newState == PlayState.PAUSED);
    seekBar.setEnabled(enabled); // 核心:未播放時禁用 SeekBar
    seekBar.setClickable(enabled);
    if (!enabled) seekBar.setProgress(0); // 重置進度
}

核心原則

  1. 狀態機管理:明確播放器狀態,UI 組件根據狀態啟用/禁用。
  2. 前置檢查:所有 MediaPlayer 操作前檢查 mediaPlayer != null 且狀態合法。
  3. 用戶拖動標記:isUserSeeking 區分用戶拖動與代碼自動更新進度,避免衝突。
  4. 視覺反饋:禁用時 SeekBar 變灰/透明,提示用戶不可操作。

此模式適用於所有媒體播放控件(VideoView、ExoPlayer、MediaController),是穩健播放器開發的基礎範式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved