这次介绍一个多功能音乐播放器,记得是大二那年寒假写的,实现的主要功能就是音乐播放,带进度条控制,扫描本地音乐,上一曲下一曲,播放类型(单曲循环,顺序播放,随机播放),APP主题换肤,背景图更换等,功能都比较基础,基本上如果你不会的话,跟着我的思路,应该都是能实现的,预计会在以后加入歌词的功能。
在开始前,先放一张最后的效果图吧,我个人喜欢的风格,简约,美观。
目录
1.实现扫描本地音乐
2.音乐的播放与控制
3.关联进度条seekbar,自定义seekbar
4.单曲循环,顺序播放,随机播放的实现
5.设置喜爱音乐
6.播放列表背景图设置与保存
7.实现APP主题换肤的功能
正文
1.实现扫描本地音乐
这里为了将每个系统里面存放的音乐抽象出来,也是为了方便管理,先定义一个音乐类Song,代码如下
public class Song {
/** * 歌手 */
private String singer;
/** * 歌曲名 */
private String song;
/** * 歌曲的地址 */
private String path;
/** * 歌曲长度 */
private int duration;
/** * 歌曲的大小 */
private long size;
public String getSinger() {
return singer;
}
public void setSinger(String singer) {
this.singer = singer;
}
public String getSong() {
return song;
}
public void setSong(String song) {
this.song = song;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
public long getSize() {
return size;
}
public void setSize(long size) {
this.size = size;
}
}
然后我们再写一个工具类,这个工具类实现的功能就是扫描系统中的本地音乐,返回一个List<Song>集合,供我们使用,代码如下
public class MusicUtils {
/**
* 扫描系统里面的音频文件,返回一个list集合
*/
public static List<Song> getMusicData(Context context) {
List<Song> list = new ArrayList<>();
Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null,
MediaStore.Audio.AudioColumns.IS_MUSIC);
if (cursor != null) {
while (cursor.moveToNext()) {
Song song = new Song();
song.setSong( cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME)));
song.setSinger( cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST)));
song.setPath(cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA)));
song.setDuration( cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION)));
song.setSize( cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE)));
if (song.getSize() > 1000 * 800) {//过滤掉短音频
// 分离出歌曲名和歌手
if (song.getSong().contains("-")) {
String[] str = song.getSong().split("-");
song.setSinger( str[0]);
song.setSong( str[1]);
}
list.add(song);
}
}
// 释放资源
cursor.close();
}
return list;
}
//格式化时间
public static String formatTime(int time) {
if (time / 1000 % 60 < 10) {
return time / 1000 / 60 + ":0" + time / 1000 % 60;
} else {
return time / 1000 / 60 + ":" + time / 1000 % 60;
}
}
}
然后,在布局里定义一个Listview,再给Listview写一个适配器,一般继承自BaseAdapter,adapter代码如下
public class MyAdapter extends BaseAdapter {
private Context context;
private List<Song> list;
private int position_flag = 0;
public MyAdapter(MainActivity mainActivity, List<Song> list) {
this.context = mainActivity;
this.list = list;
}
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int i) {
return list.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder = null;
if (view == null) {
holder = new ViewHolder();
// 引入布局
view = View.inflate(context, R.layout.list_item, null);
// 实例化对象
holder.song = (TextView) view.findViewById(R.id.item_mymusic_song);
holder.singer = (TextView) view
.findViewById(R.id.item_mymusic_singer);
holder.duration = (TextView) view
.findViewById(R.id.item_mymusic_duration);
holder.position = (TextView) view
.findViewById(R.id.item_mymusic_postion);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// 给控件赋值
String string_song = list.get(i).getSong();
if (string_song.length() >= 5
&& string_song.substring(string_song.length() - 4,
string_song.length()).equals(".mp3")) {
holder.song.setText(string_song.substring(0,
string_song.length() - 4).trim());
} else {
holder.song.setText(string_song.trim());
}
holder.singer.setText(list.get(i).getSinger().toString().trim());
// 时间转换为时分秒
int duration = list.get(i).getDuration();
String time = MusicUtils.formatTime(duration);
holder.duration.setText(time);
return view;
}
class ViewHolder {
TextView song;// 歌曲名
TextView singer;// 歌手
TextView duration;// 时长
TextView position;// 序号
}
}
adapter里面的列表项布局代码如下
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"