TextView не рисует изнутри кнопка onClick - PullRequest
1 голос
/ 03 марта 2011

Я пытаюсь создать приложение для потоковой передачи музыки. Пока все работает просто отлично. Я использую

MediaPlayer.create(thisContext, Uri.parse(PATH_TO_STREAM));

удобный метод для подготовки бесконечного потока (24x7 mp3-поток). Он зависает всего на несколько секунд при вызове, который я аккуратно скрыл в своем методе startPlaying (). Кнопка не показывает, что на нее нажимают, пока не начнется воспроизведение потока, так что сначала пользователю остается задаться вопросом, нажали ли они кнопку или пропустили. Поэтому я хочу обновить метку TextView рядом с кнопкой с надписью «Подождите ...» или «Буферизация» и т. Д., А затем очистить ее после запуска потока, чтобы пользователь знал, что он нажал кнопку «ОК». Даже если я выполнил это при отладке, метка не обновится до тех пор, пока не будет завершен onClick. Я могу закомментировать последнюю строку, которая очищает текст метки и может видеть, что она установлена ​​на «Буферизация ...» ОК. Но только после выхода из onClick. Это ограничение использования метода create () медиаплеера?

final Button startbutton = (Button) findViewById(R.id.Button01);
this.tvBuffering = (TextView) findViewById(R.id.tvBuffering);

startbutton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            tvBuffering.setText("Buffering...");
            //do something like invalidate() here??
            startPlaying();  //blocks here for a few seconds to buffer then plays.
            tvBuffering.setText(" "); //clear the text since it's playing by now.
        }   
    });

1 Ответ

1 голос
/ 06 августа 2011

Не очень хорошая идея, чтобы намеренно включать такого рода задержки в пользовательском интерфейсе, потому что это заблокирует практически все, что пользователь пытается сделать в течение этих нескольких секунд.Я предполагаю, что ваш startPlaying() включает в себя вызов prepare(), а также start().При получении данных из источника, который не будет немедленно доступен (например, из потока), вы должны использовать вместо него prepareAsync(), который начнет подготовку и немедленно вернется вместо блокировки, пока подготовка не будет завершена.

Выможете прикрепить обратный вызов к вашему MediaPlayer, чтобы затем выполнить действие после завершения подготовки через MediaPlayer.OnPreparedListener

. Вот простой пример.Обратите внимание, что ваш OnClickListener может оставаться прежним, если вы измените prepare() в методе startPlaying() на prepareAsync() и удалите вызов start() из startPlaying().

startbutton.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        tvBuffering.setText("Buffering...");

        startPlaying();  //which should call prepareAsync() instead of prepare()
                         //and have no call to start()
    }   
});

mYourMediaPlayer.setOnPreparedListener( new MediaPlayer.OnPreparedListener() {
    @Override
    public void onPrepared(MediaPlayer mp) {
        start();
        tvBuffering.setText(" ");
    }
});
...