音乐播放器第三版-增加拖动进度条
给音乐播放器增加了拖动进度条功能,进度条显示当前音乐播放进度,拖动后可以从拖动结束位置开始播放。
步骤:
- 布局中增加拖动进度条。
- 创建Handler,对seekbar进行监听和设置。
布局
<TextView
android:id="@+id/tv_current_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toTopOf="@+id/seekBar"
app:layout_constraintStart_toStartOf="@+id/seekBar"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/tv_total_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toTopOf="@id/seekBar"
app:layout_constraintEnd_toEndOf="@id/seekBar"/>
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:max="100"
app:layout_constraintTop_toTopOf="@+id/iv_splitline"
tools:layout_editor_absoluteX="0dp" />
布局中添加一个展示当前播放音乐的进度的TextView,一个展示当前播放的音乐的时长的TextView和一个进度条。
Handler
主活动中:
@SuppressLint("HandlerLeak")
private final Handler handler = new Handler(){
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == 0x01) {
tv_cur_time.setText(getString(R.string.timeiszeero));
tv_cur_time.setText(formatTime(musicService.getCurrent()));
tv_total_time.setText(formatTime(musicBean.getDuration()));
seekBar.setProgress(musicService.getCurrent());
seekBar.setMax(musicBean.getDuration());
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
isSeekBarChanging = false;
musicService.seekTo(seekBar.getProgress());
}
});
handler.sendEmptyMessage(0x01);
}
}
};
private final ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
musicService = ((MusicService.MusicBinder) service).getService();
handler.sendEmptyMessage(0x01);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
@SuppressLint("DefaultLocale")
private String formatTime(int time) {
int ms2s = (time / 1000);
int minute = ms2s / 60;
int second = ms2s % 60;
return String.format("%02d:%02d", minute, second);
}
Service中:
public void seekTo(int progress) {
currentMediaPlayer.seekTo(progress);
}
public int getCurrent() {
return currentMediaPlayer.getCurrentPosition();
}
首先,在主活动中创建Handler,目的是在线程中对进度条进行监听和设置。先获取了当前正在播放的音乐的时长和播放进度并加载到界面中。
然后,开始对进度条进行监听,设置一个boolean变量,当进度条开始改变时为true,进度条停止改变时为false,当前音乐从进度条停止位置进行播放。
进度条是如何实时获得当前播放音乐的位置:
在service中写一个getCurrent()方法,在此方法中返回播放位置。注意:这里不能使用全局变量currentPositionInMusic,因为currentPositionInMusic记录的是按下暂停键后的位置,进度条需要的是实时位置,所以这里只能调用Mediaplayer的getCurrentPostion()方法。
从进度条停止播放则是依靠Mediaplayer的seekTo(int position)方法。seekTo(int position)让音乐从position位置开始播放。
那在何处发送消息呢?
在Service创建连接后发送消息,因为进度条是和当前正在播放的音乐绑定在一起的,只有当服务创建连接后,且正在运行,音乐才会开始播放且转入后台。
同时利用增加的Handler,把UI更新代码进行优化。
源码地址:https://gitee.com/luozhaosong/new-music-app