开发者

TextView not drawing from within button onClick

I am trying to create a music streaming app. So far it works just fine. I am using the

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

convenience method to prepare the infinite stream (24x7 mp3 stream). It hangs for just a few seconds on this call which I have neatly tucked into my startPlaying() method. The button doesn't show it's getting clicked until after the stream starts playing so at first the user is left wondering if they tapped the button or missed. So I want to update a TextView label next to the button that says "Wait..." or "Buffering" etc. then clear it after the stream starts so the user knows they pressed the button OK. Even if I step through this in debug the label doesn't update until after the onClick is finished. I can comment out the last line that clears the label text and can see it set to "Buffering..." OK. But only after it exits the onClick.开发者_StackOverflow Is this a limitation of using the media player create() method?

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.
        }   
    });


It's not such a great idea to intentionally include that sort of delay in the UI, because that will block just about anything the user tries to do for those few seconds. I'm assuming that your startPlaying() includes a call to prepare(), as well as start(). When taking data from a source that won't be immediately available (such as a stream), you should use prepareAsync() instead, which will start preparation and return immediately instead of blocking until preparation is complete.

You can attach a callback to your MediaPlayer to then take action once preparation has completed through a MediaPlayer.OnPreparedListener

Here's a simple example. Note that your OnClickListener can stay the same, as long as you change the prepare() in the startPlaying() method to prepareAsync() and remove the start() call from 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(" ");
    }
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜