9

Vraag over seekbar, android – undefined

Это правильный способ обновления ProgressBar при воспроизведении Media? Я подумал, что в MediaPlayer будет обратный вызов, но я не смог его найти.

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();

С наилучшими пожеланиями.

  • Та же проблема, что и раньше, я использовал ваше предложение ... с CountDownTimer: progress.setProgress (mediaPlayer.getCurrentPosition ()); - до сих пор нет понятия, что лучше;) И спать для меня и мои философские вопросы.

    door pouzzler
  • @pouzzler Таймер обратного отсчета работает в другом потоке, единственное отличие состоит в том, что он не использует фактический прогресс. Я напишу пример с резьбой

    door
  • Таймер не блокирует пользовательский интерфейс, поэтому я предполагаю, что он находится в другом потоке. Поэтому я полагаю, что это то же самое. Я хотел бы быть достаточно умным, чтобы понять эти вещи.

    door pouzzler
  • О, да, спасибо, что заметили это - я исправлю это сейчас.

    door
  • @pouzzler слишком поздно ... но добро пожаловать :)

    door
  • Мне нравится этот подход, но я думаю, что вы забыли добавить loop /, в то время как run () выполняется не раз

    door
  • ну не надо, я понял. Спасибо :)

    door pouzzler
  • @pouzzler - Добро пожаловать! Рассмотрение класса MediaController отлично подходит для того, чтобы дать вам идеи по созданию собственного контроллера.

    door
  • Вторая ссылка исчезла из-за удаления DMCA:github.com/OESF/OHA-Android-4.0.1_r1.0

    door
  • Спасибо, именно то, что я искал.

    door pouzzler
3 antwoorden
  • 18

    Лично я начинаю с темы, которая проверяет

    getCurrentPosition() каждые 200 мс или около того, пока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();
    }
    

  • 2

    Наиболее эффективный способ состоит в том

    чтобы использовать ответ 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());
    }
    

  • 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);