在android中使用seekbar和音乐
实际上,我正在创建一个带有按钮、搜索栏和图像的应用程序。该按钮用于播放/暂停音乐。添加seekbar之前,音乐播放流畅。但是,在为seekbar编写代码以使其与音乐的位置同步后,音乐似乎有点起伏。 另外,我想重置seekbar的位置以开始播放,并在音乐播放结束后将文本打开按钮更改为播放。 有谁能告诉我为什么在执行seekbar之后音乐会变得波涛汹涌? 另外,建议我在音乐播放完毕后如何处理。 我使用的代码如下:在android中使用seekbar和音乐,android,android-mediaplayer,android-seekbar,Android,Android Mediaplayer,Android Seekbar,实际上,我正在创建一个带有按钮、搜索栏和图像的应用程序。该按钮用于播放/暂停音乐。添加seekbar之前,音乐播放流畅。但是,在为seekbar编写代码以使其与音乐的位置同步后,音乐似乎有点起伏。 另外,我想重置seekbar的位置以开始播放,并在音乐播放结束后将文本打开按钮更改为播放。 有谁能告诉我为什么在执行seekbar之后音乐会变得波涛汹涌? 另外,建议我在音乐播放完毕后如何处理。 我使用的代码如下: public class MainActivity extends ActionBar
public class MainActivity extends ActionBarActivity {
private MediaPlayer song;
private SeekBar seekbar;
private final Handler handler = new Handler();
private final Runnable updatePositionRunnable = new Runnable() {
public void run() {
updatePosition();
}
};
//private boolean isPlaying = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment())
.commit();
}
seekbar = (SeekBar)findViewById(R.id.musicSeekBar);
song = MediaPlayer.create( MainActivity.this, R.raw.xyz);
seekbar.setMax(song.getDuration());
final Button playButton = (Button)findViewById(R.id.playButton);
playButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(song.isPlaying()){
playButton.setText("Play");
song.pause();
//isPlaying = false;
handler.removeCallbacks(updatePositionRunnable);
}
else{
playButton.setText("Pause");
song.start();
//isPlaying = true;
updatePosition();
}
}
});
song.setOnCompletionListener(new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
playButton.setText("Play");
//seekbar.setProgress(0);
//mp.stop();
}
});
seekbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
song.seekTo(progress);
}
});
private void updatePosition(){
handler.removeCallbacks(updatePositionRunnable);
seekbar.setProgress(song.getCurrentPosition());
handler.postDelayed(updatePositionRunnable, 2000);
}
@Override
public void onBackPressed() {
super.onBackPressed();
song.stop();
song.release();
}
当您每2秒从updatePosition方法更新seekbar上的进度时,将调用侦听器中的onProgressChanged方法,这将设置播放位置并导致轻微的光点。您可能期望onProgressChanged仅在用户与SeekBar交互时调用,但不幸的是,事实并非如此 我不知道有什么干净的解决办法。您可以做的是在调用seekbar.setProgress之前在代码中设置一个布尔标志,指示下一个onProgressChanged回调不是由用户引起的,因此您可以忽略它。为此,您应该使用AtomicBoolean,因为事件可能来自不同的线程。这对我很有用:
sBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
boolean userTouch;
@Override
public void onStopTrackingTouch(SeekBar arg0) {
userTouch = false;
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
userTouch = true;
}
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
if(mPlayer.isPlaying() && arg2)
mPlayer.seekTo(arg1);
}
});
不需要布尔userTouch,因为onProgressChanged中的第三个参数是布尔值,如果用户发起了进度更改,则该参数为真。这使得您对onStart的覆盖。。。最重要的是。。。无用的只是想帮你保存一些代码=