2012-04-03 49 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