最近在做android mp3的项目,做到进度控制的使用SeekBar的时候遇到在开始播放的时候,歌曲总是重新播放,由于有工作,这个问题找了3天,下面跟大家分享下经验。
由于代码过多,贴上主要的代码:
public class PlaySeekBar extends SeekBar {
private Timer timer;
private TimerTask timer_task;
private int progress;
private int duration;
private Handler handler;
private Runnable runnable;
private OnPlayChangedListener listener;
private boolean pressed = false;
private boolean start = false;
/**
* construct
* */
public PlaySeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}
/**
* construct
* */
public PlaySeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}
/**
* construct
* */
public PlaySeekBar(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}
public void setOnPlayChangedListener(OnPlayChangedListener listener) {
this.listener = listener;
}
/**
* set total time of music before play music
*
* @param duration
* total time of music
* @return none
* */
public void SetPlayDuration(int duration) {
this.duration = duration;
setMax(duration);
}
/**
* set current time of music
*
* @param progress
* current time of music
* @return none
* */
public void SetCurPlayProgress(int progress) {
this.progress = progress;
setProgress(progress);
}
/**
* when you press the seekbar, set the flag
*
* @param flag
* whether press or not
* @return none
* */
public void setPressedFlag(boolean flag) {
pressed = flag;
}
/**
* @param none
* @return flag whether press or not
* */
public boolean getPressedFlag(){
return pressed;
}
/**
* stop timer
*
* @param none
* @return none
* */
public void StopTimer() {
start = false;
}
/**
* start timer
*
* @param none
* @return none
* */
public void StartTimer() {
start = true;
}
/**
* init data
*
* @param none
* @return none
* */
private void init() {
handler = new Handler();
timer_task = new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
if ( ((pressed == true) || (start == false))) {
return;
}
handler.post(runnable);
}
};
timer = new Timer();
timer.schedule(timer_task, 0, 500);
runnable = new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
update_progress();
}
};
}
/**
* destroy timer and timer task
* */
public void finish(){
// cancel timer
timer.cancel();
// cancel timer task
timer_task.cancel();
}
/**
* update seekbar display per second
*
* @param none
* @return none
* */
private void update_progress() {
progress++;
if (progress >= duration) {
this.setProgress(0);
if (listener != null) {
listener.OnChanged();
}
} else {
if (listener != null) {
listener.OnChanged();
}
}
//setProgress(progress);
}
}
这个是继承SeekBar的自定义的类,主要是自配一个定时器,设置每500ms调用一次timer_task方法,在timer_task中通过handler向控件本身的线程发消息,用于更新进度,更新进度的方式是由一个接口OnPlayChangedListener,接口原型:
public interface OnPlayChangedListener {
/**
* @param finished
* true:finish; false:not finish
* @param progress
* current time of music
* @return none
* */
public void OnChanged();
}
主界面通过注册监听,来更新时间的显示和进度。
另外在主界面上,设置SeekBar的变化监听,主要为了拖动SeekBar来控制播放的位置,主要代码:
SeekBar.OnSeekBarChangeListener play_seek_listener = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
// TODO Auto-generated method stub
if (play_progress.getPressedFlag() == true) {
mp3_player.Mp3Player_Seek(arg1 * 1000);
}
}
@Override
public void onStartTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
play_progress.setPressedFlag(true);
}
@Override
public void onStopTrackingTouch(SeekBar arg0) {
// TODO Auto-generated method stub
play_progress.setPressedFlag(false);
}
};
onStartTrackingTouch,用来监听用户按下SeekBar开始调整位置。
onStopTrackingTouch,用来监听用户停止调整位置。
onProgressChanged,用来监听用户调整的位置。
onProgressChanged中,如果不加if (play_progress.getPressedFlag() == true)这个判断,那么每秒更新SeekBar后onProgressChanged反上来的第二个参数是0,通过这个设置的MediaPlayer就是0,所以一直在重新播放。
本人为初学者,通过这次的错误明白了SeekBar的onProgressChanged回调方法的作用,为了以后不再犯错,在此mark下。