2012-04-03 83 views
8

這是在播放媒體時更新ProgressBar的正確方法嗎?我想在MediaPlayer中會有一個回調,但我找不到它。MediaPlayer,ProgressBar

mediaPlayer.start(); 
final SeekBar progress = (SeekBar) dialog.findViewById(R.id.seekBar1); 
progress.setMax(mediaPlayer.getDuration()); 
new CountDownTimer(mediaPlayer.getDuration(), 250) { 
    public void onTick(long millisUntilFinished) { 
    progress.setProgress(progress.getProgress() + 250); 
    } 
    public void onFinish() {} 
}.start(); 

此致敬意。

回答

10

android.widget.MediaController看看,它有一個進度條。

它們使用遞歸調用自己的處理程序(如果適用)。您可以將延遲設置爲經常更新進度欄。

請注意,控制器可以顯示或隱藏以及用戶拖動,當然 - 視頻可以停止。這些是在另一次遞歸調用更新條之前進行各種檢查(!mDragging && mShowing && mVideoView.isPlaying())的原因。

protected Handler mHandler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message msg) 
    { 
     int pos; 
     switch (msg.what) 
     { 
      // ... 

      case SHOW_PROGRESS: 
       pos = setProgress(); 
       if (!mDragging && mShowing && mVideoView.isPlaying()) 
       { 
        msg = obtainMessage(SHOW_PROGRESS); 
        sendMessageDelayed(msg, 1000 - (pos % 1000)); 
       } 
       break; 

      // ... 
     } 
    } 
}; 

要啓動它關閉使用:

mHandler.sendEmptyMessage(SHOW_PROGRESS); 

它將停止本身,但你應該使用取消最後的未決請求:

mHandler.removeMessages(SHOW_PROGRESS); 
+1

謝謝,正是我所尋找的。 – pouzzler 2012-04-03 20:43:46

+0

@pouzzler - 不客氣!查看MediaController類非常適合您提供有關製作自定義控制器的想法。 – 2012-04-03 21:16:14

+0

由於數字千年版權法案刪除,第二個鏈接不見了:https://github.com/OESF/OHA-Android-4.0.1_r1.0 – astromme 2017-03-19 19:23:14

16

就個人而言,我開始,檢查getCurrentPosition()每200ms左右,直到onCompletion()事件被髮了一個帖子:

private class MediaObserver implements Runnable { 
    private AtomicBoolean stop = new AtomicBoolean(false); 

    public void stop() { 
    stop.set(true); 
    } 

    @Override 
    public void run() { 
    while (!stop.get()) { 
     progress.setProgress(mediaPlayer.getCurrentPosition()); 
     Thread.sleep(200); 
    } 
    } 
} 

private MediaObserver observer = null; 

public void runMedia() { 
    mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener{ 
    @Override 
    public void onCompletion(MediaPlayer mPlayer) { 
     observer.stop(); 
     progress.setProgress(mPlayer.getCurrentPosition()); 
    } 
    }); 
    observer = new MediaObserver(); 
    mediaPlayer.start(); 
    new Thread(observer).start(); 
} 
+0

計時器不會阻止用戶界面,所以我想這是在另一個線程。所以我想這是一樣的。我希望自己足夠聰明,能把這些事情弄清楚。 – pouzzler 2012-04-03 20:08:06

+0

@pouzzler倒數計時器在另一個線程中運行,唯一的區別是它不使用實際進度。我會寫一個線程示例 – JRaymond 2012-04-03 20:19:24

+0

啊,不需要,我明白了。謝謝:) – pouzzler 2012-04-03 20:27:54

1

最有效的方法是使用JRaymond的回答和EventBus

private class MediaObserver implements Runnable { 
    private AtomicBoolean stop = new AtomicBoolean(false); 
    public void stop() { 
     stop.set(true); 
    } 

    @Override public void run() { 
     while (!stop.get()) { 
      try { 
       if (player.isPlaying()) 
       sendMsgToUI(player.getCurrentPosition(), 
          player.getDuration()); 
      } catch (Exception e){e.printStackTrace();} 
      try { 
       Thread.sleep(100); 
      } catch (InterruptedException e) { e.printStackTrace(); } 
     } 
    } 
} 

private MediaObserver observer = null; 

public void runMedia() { 
    observer = new MediaObserver(); 
    new Thread(observer).start(); 
} 

//handles all the background threads things for you 
private void sendMsgToUI(int position) { 
    ChangingEvent event = new ChangingEvent(position); 
    EventBus.getDefault().post(event); 
} 

ChangingEvent類看起來類似的東西:

public class ChangingEvent { 
    private int position; 

    public ChangingEvent(int position) { 
     this.position= position; 
    } 

    public int getPosition() { 
     return position; 
    } 
} 

,並在您的活動或片段所有你需要做的就是

class YouClass extends Activity { 
    private EventBus eventBus = EventBus.getDefault(); 
} 

@Override protected void onCreate(Bundle savedInstanceState) { 
    //your code 
    eventBus.register(this); 
} 
//eventbus that updates UI 
public void onEventMainThread(ChangingEvent event) { 
    //seekbar or any other ui element 
    seekBar.setProgress(event.getPosition()); 
} 
+0

我喜歡這種方法,但我想你忘了添加循環/ while run run()被執行的次數不止一次 – 2015-07-20 15:32:19

+0

噢,是的,謝謝你注意到 - 我現在就改正它。 – 2015-07-21 01:11:01