Android初级,MediaPlayer播放音乐,进度条滑动及唱片转动功能实现
来源:互联网 发布:pl10空空导弹 知乎 编辑:程序博客网 时间:2024/05/16 15:04
最近在做仿网易云音乐播放器的实训项目,学习完后写此博客,一方面巩固自己理解,一方面方便各位浏览。
读完本文你将了解到:
- 如何利用MediaPlayer播放音乐
- 如何设置音乐进度条并实现自动滚动及手动定位
- 如何实现唱片转动功能
1.效果图
2.代码如下
Layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">//设置背景图片 <ImageView android:id="@+id/listen_background_iv" android:layout_width="match_parent" android:layout_height="match_parent" android:scaleType="centerCrop" android:src="@mipmap/img1" /> <RelativeLayout android:id="@+id/listen_rl" android:layout_width="match_parent" android:layout_height="70dp" android:layout_weight="1">//设置返回按钮图片 <ImageView android:id="@+id/listen_back1_iv" android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentStart="true" android:layout_centerVertical="true" android:layout_marginLeft="5dp" android:src="@mipmap/back1" />//设置歌曲名 <TextView android:id="@+id/listen_title_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="15dp" android:layout_marginTop="8dp" android:layout_toRightOf="@id/listen_back1_iv" android:text="成都" android:textColor="#f9f7f7" android:textSize="20sp" />//设置歌手名 <TextView android:id="@+id/listen_artist_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignStart="@id/listen_title_tv" android:layout_below="@id/listen_title_tv" android:layout_marginTop="5dp" android:text="赵雷-" android:textColor="#aeabab" android:textSize="15sp" />//设置专辑名 <TextView android:id="@+id/listen_album_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignTop="@id/listen_artist_tv" android:layout_toRightOf="@id/listen_artist_tv" android:text="成都" android:textColor="#aeabab" android:textSize="15sp" />//设置“分享”按钮(本代码中未实现) <ImageView android:layout_width="30dp" android:layout_height="30dp" android:layout_alignParentEnd="true" android:layout_centerVertical="true" android:layout_marginRight="15dp" android:src="@mipmap/share" />//设置布局间的线 <View android:layout_width="match_parent" android:layout_height="0.5dp" android:layout_below="@id/listen_artist_tv" android:background="#bababa" /> </RelativeLayout>//设置唱片圆盘 <ImageView android:id="@+id/listen_changpian_img" android:layout_width="250dp" android:layout_height="250dp" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:src="@mipmap/play_page_disc" />//设置圆盘上的指针 <ImageView android:id="@+id/listen_zhizhen_iv" android:layout_width="100dp" android:layout_height="150dp" android:layout_below="@id/listen_rl" android:layout_centerHorizontal="true" android:src="@mipmap/play_page_needle" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentTop="true" android:layout_marginBottom="15dp"> <RelativeLayout android:id="@+id/listen_play" android:layout_width="match_parent" android:layout_height="60dp" android:layout_alignParentBottom="true" android:layout_marginBottom="0dp">//设置“暂停” <ImageView android:id="@+id/listen_pause1_img" android:layout_width="60dp" android:layout_height="60dp" android:layout_centerHorizontal="true" android:layout_centerVertical="true" android:layout_marginTop="10dp" android:src="@mipmap/icon_music_circle_pause" />//设置“上一首” <ImageView android:id="@+id/listen_back_img" android:layout_width="40dp" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:layout_toLeftOf="@id/listen_pause1_img" android:src="@mipmap/back_w" />//设置下一首 <ImageView android:id="@+id/listen_next_img" android:layout_width="40dp" android:layout_height="40dp" android:layout_centerVertical="true" android:layout_marginLeft="30dp" android:layout_toRightOf="@id/listen_pause1_img" android:src="@mipmap/next_w" /> </RelativeLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_above="@id/listen_play" android:layout_marginBottom="10dp" android:orientation="horizontal" android:paddingLeft="10dp" android:paddingRight="10dp">//设置“当前歌曲时间” <TextView android:id="@+id/listen_current_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="00:00" />//设置“进度条” <SeekBar android:id="@+id/listen_jindutiao_sb" android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" />//设置“歌曲总时长” <TextView android:id="@+id/listen_length_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="02:30" /> </LinearLayout> </RelativeLayout></RelativeLayout>
MusicActivity
首先对需要用到的控件进行定义:
private ImageView backIv; private ImageView nextIv;//"下一首" private ImageView discsmap;//"唱片" private ImageView pauseIv;//“暂停” private MediaPlayer mediaPlayer;//"MediaPlayer" private ObjectAnimator animator;//运用ObjectAnimator实现转动 private TextView currentTv;//"当前时间" private TextView totalTv;//“歌曲总时间” private int totalTime;//“歌曲总时长,用于获取歌曲时长” private SeekBar jindutiaoSb; //"进度条" private boolean isStop;//“停止” private int position;
新建方法link()进行绑定ID:
private void Link() { backIv = findViewById(R.id.listen_back_img); nextIv = findViewById(R.id.listen_next_img); discsmap = findViewById(R.id.listen_changpian_img); pauseIv = findViewById(R.id.listen_pause1_img); currentTv = findViewById(R.id.listen_current_tv); totalTv = findViewById(R.id.listen_length_tv); jindutiaoSb = findViewById(R.id.listen_jindutiao_sb); }
新建play()方法用于歌曲播放、唱片打碟功能,及进度条简要设置
private void play() { mediaPlayer.reset();//进行重置 Bitmap disces = BitmapFactory.decodeResource(getResources(), R.mipmap.circumstance); } /////////////////////歌曲播放//////////////////////////////////////////////////// try { mediaPlayer.setDataSource(music.path); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } backIv.setOnClickListener(this); nextIv.setOnClickListener(this); pauseIv.setOnClickListener(this); ///////////////////////////////////唱片打碟///////////////////////////////////////////// animator = ObjectAnimator.ofFloat(discsmap, "rotation", 0f, 360.0f); animator.setDuration(10000); animator.setInterpolator(new LinearInterpolator());//匀速 animator.setRepeatCount(-1);//设置动画重复次数(-1代表一直转) animator.setRepeatMode(ValueAnimator.RESTART);//动画重复模式 animator.start(); ////////////////////////////////进度条///////////////////////////////////////////////// totalTv.setText(formatTime(music.length));//获取歌曲时长并作为文本显示 totalTime = music.length;//获取歌曲时长 new Thread(new SeekBarThread()).start();//线程开始 jindutiaoSb.setMax(music.length);//设置音乐长度最大值,从而使音乐长度简单且可控 ////////////////////////////指针拨动//////////////////////////////////////////////////// animator1 = ObjectAnimator.ofFloat(zhizhenmap, "rotation", -60f, 0.0f); animator1.setDuration(900); animator1.setRepeatCount(0);//设置动画重复次数(-1代表一直转) animator1.start(); }
获取歌曲时长并将其转化为“分:秒”形式:
///////////////规定需要的时间形式/////////////////////// private String formatTime(int length) { Date date = new Date(length);//调用Date方法获值 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss");//规定需要形式 String TotalTime = simpleDateFormat.format(date);//转化为需要形式 return TotalTime; }
设置事件监听:
@Override public void onClick(View view) { switch (view.getId()) { case R.id.listen_back_img://当点击“上一首”按钮 position--;//数组递减 if (position == -1) { position = Common.musicList.size() - 1; } play(); break; case R.id.listen_next_img: position++; if (position == Common.musicList.size()) { position = 0; } play(); case R.id.listen_pause1_img: if (mediaPlayer.isPlaying()) { mediaPlayer.pause();//当正在播放时,点击“暂停” animator.pause(); pauseIv.setImageResource(R.mipmap.start); } else { mediaPlayer.start();//否则,播放 pauseIv.setImageResource(R.mipmap.icon_music_circle_pause); animator.resume(); animator1.resume(); } default: break; } }
建立销毁方法:
@Override protected void onDestroy() { super.onDestroy(); mediaPlayer.reset(); isStop = true; }
运用多线程进行进度条及位置更新:
class SeekBarThread implements Runnable { @Override public void run() { while (mediaPlayer != null && isStop == false) { // 将SeekBar位置设置到当前播放位置 handler.sendEmptyMessage(mediaPlayer.getCurrentPosition()); try { // 每100毫秒更新一次位置 Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } } } }
定义Handler进行接收:
private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); jindutiaoSb.setProgress(msg.what); currentTv.setText(formatTime(msg.what)); } };
整体代码如下:
package com.example.listviewpagerviewdemo;public class MusicActivity extends AppCompatActivity implements View.OnClickListener {//定义各类控件 private ImageView backIv; private ImageView nextIv; private int position; private ImageView discsmap; private ImageView pauseIv; private MediaPlayer mediaPlayer; private ObjectAnimator animator; private TextView currentTv; private TextView totalTv; private int totalTime; private SeekBar jindutiaoSb; private boolean isStop; //接受多线程信息,安卓中不允许主线程实现UI更新 private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); jindutiaoSb.setProgress(msg.what); currentTv.setText(formatTime(msg.what)); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.listen_layout);//获取传值 Intent intent = getIntent(); position = intent.getIntExtra("i", 0);//将传入的值赋给position//获取mediaplayer mediaPlayer = new MediaPlayer(); Link();//绑定ID方法 play();//歌曲播放及一系列操作方法/////////////////////////获取进度条点击位置并使歌曲跳转到该位置//////////////////////////////////// jindutiaoSb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int i, boolean b) { if (b) { mediaPlayer.seekTo(i); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); } private void play() { mediaPlayer.reset(); Music music = Common.musicList.get(position);//获取传来的值 Bitmap disces = BitmapFactory.decodeResource(getResources(), R.mipmap.circumstance); /////////////////////歌曲播放//////////////////////////////////////////////////// try { mediaPlayer.setDataSource(music.path); mediaPlayer.prepare(); mediaPlayer.start(); } catch (IOException e) { e.printStackTrace(); } backIv.setOnClickListener(this); nextIv.setOnClickListener(this); pauseIv.setOnClickListener(this); ///////////////////////////////////唱片打碟///////////////////////////////////////////// animator = ObjectAnimator.ofFloat(discsmap, "rotation", 0f, 360.0f); animator.setDuration(10000); animator.setInterpolator(new LinearInterpolator());//匀速 animator.setRepeatCount(-1);//设置动画重复次数(-1代表一直转) animator.setRepeatMode(ValueAnimator.RESTART);//动画重复模式 animator.start(); ////////////////////////////////进度条///////////////////////////////////////////////// totalTv.setText(formatTime(music.length)); totalTime = music.length; new Thread(new SeekBarThread()).start(); jindutiaoSb.setMax(music.length); ////////////////////////////指针拨动//////////////////////////////////////////////////// animator1 = ObjectAnimator.ofFloat(zhizhenmap, "rotation", -60f, 0.0f); animator1.setDuration(900); animator1.setRepeatCount(0);//设置动画重复次数(-1代表一直转) animator1.start(); } ///////////////获取歌曲时常/////////////////////// private String formatTime(int length) { Date date = new Date(length); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss"); String TotalTime = simpleDateFormat.format(date); return TotalTime; } private void Link() { backIv = findViewById(R.id.listen_back_img); nextIv = findViewById(R.id.listen_next_img); discsmap = findViewById(R.id.listen_changpian_img); pauseIv = findViewById(R.id.listen_pause1_img); currentTv = findViewById(R.id.listen_current_tv); totalTv = findViewById(R.id.listen_length_tv); jindutiaoSb = findViewById(R.id.listen_jindutiao_sb); } @Override public void onClick(View view) { switch (view.getId()) { case R.id.listen_back_img: position--; if (position == -1) { position = Common.musicList.size() - 1; } play(); break; case R.id.listen_next_img: position++; if (position == Common.musicList.size()) { position = 0; } play(); case R.id.listen_pause1_img: if (mediaPlayer.isPlaying()) { mediaPlayer.pause(); animator.pause(); pauseIv.setImageResource(R.mipmap.start); } else { mediaPlayer.start(); pauseIv.setImageResource(R.mipmap.icon_music_circle_pause); animator.resume(); animator1.resume(); } default: break; } } @Override protected void onDestroy() { super.onDestroy(); mediaPlayer.reset(); isStop = true; } class SeekBarThread implements Runnable { @Override public void run() { while (mediaPlayer != null && isStop == false) { // 将SeekBar位置设置到当前播放位置 handler.sendEmptyMessage(mediaPlayer.getCurrentPosition()); try { // 每100毫秒更新一次位置 Thread.sleep(80); } catch (InterruptedException e) { e.printStackTrace(); } } } }}
Tip:
本文未将传入值进行代码讲解,仅对实现播放音乐、进度条滑动及唱片功能的实现进行了解析,需要注意的是,在除本文代码外我也单独地定义了一个工具类取名“Common”,用于存放Music类中定义的方法,在此也把代码给各位:
Common:
public class Common { public static List<Music> musicList = new ArrayList<>();}
Music:
public class Music { public int length;//歌曲长度 public String path;//歌曲获取路径}
除去获取歌曲的时长用setMax方法外,还有更偏重“小学数学好的人”的方法,即不采用获取setMax方法,而是将歌曲长度从毫秒用类型转换及计算转化为0-100内的整数:
float c = msg.what; jindutiaoSb.setProgress((int)(c/totalTime*100));
阅读全文
1 0
- Android初级,MediaPlayer播放音乐,进度条滑动及唱片转动功能实现
- Android之MediaPlayer播放音乐并实现进度条实例
- Android之MediaPlayer播放音乐并实现进度条实例
- Android MediaPlayer实现音乐播放
- 通过MediaPlayer实现简单的音乐播放(进度条实现快进的功能)
- MediaPlayer 音乐播放器进度条
- android如何长时间音乐播放实现MediaPlayer
- android如何长时间音乐播放实现MediaPlayer
- Android音乐播放器 -- MediaPlayer Service实现
- android MediaPlayer实现简单的音乐播放
- Android实现简单音乐播放器(MediaPlayer)
- Android实现简单音乐播放器(MediaPlayer)
- mediaplayer实现音乐播放
- android MediaPlayer 音乐播放
- android-MediaPlayer音乐播放
- android mediaPlayer 播放音乐
- Android音乐播放-MediaPlayer
- Android MediaPlayer 音乐播放
- 楼天城(百度百科)
- webstorm上使用GIt工具
- 29. My Calendar I
- 专访阿里云游戏首席架构师李刚:如何解决云服务技术两大痛点?
- 一步一步制作yaffs/yaffs2根文件系统(七)---纠正前边出现的错误
- Android初级,MediaPlayer播放音乐,进度条滑动及唱片转动功能实现
- Retrofit 上传文件
- How to setup Juniper vMX environment
- Docker安装php(使用docker pull方法)
- C3p0——数据库连接池
- 可视化图代码汇总
- STM32关于IAR和Keil中如何查看代码段的大小
- win10系统和压缩内存占用80端口 PID4
- DBMS_METADATA.GET_DDL 获取数据库里面的ddl语句