简易音乐播放器(Android(安卓)Studio)
16lz
2021-01-26
Android期末作业,临时抱佛脚(手动滑稽
分享下音乐播放的源码吧。(只能播放内嵌音乐
PS:完整工程下载及相关说明:https://download.csdn.net/download/weixin_41918712/10586908
注意事项
卫星式菜单参考:https://www.cnblogs.com/tianhengblogs/p/5265195.html
接下来是音乐播放器步骤:
- 在工程文件夹“ ..\app\src\main\res ”下,新建一个文件夹“raw”,然后把音乐放进去,命名为“ lucky.mp3 ” ;
- 在工程文件夹 “ ..\app\src\main\res\drawable ”下,放入你喜欢的图片作为播放器背景,命名为“bg1”;以及4个控制按钮(尺寸:34*30),分别命名为 “exit”,“stop”,“play”,“pause”,和菜单按钮(尺寸:45*42) “menu” ;
- 在工程文件夹 “ ..\app\src\main\res\mipmap-hdpi ”下,放入歌手海报,命名为“img”。由于要制作旋转效果,故推荐选择圆形的图片;
- 在工程文件夹“ ..\app\src\main\res ”下,新建一个文件夹“anim”,在里面新建3个xml文档,命名为“anim.xml”,“bigalpha.xml”,“smallalpha.xml”;
- “ AndroidManifest.xml ”里,在后加一句
- 在工程文件夹“ ..\app\src\main\res\values ”下,新建xml文档,命名为“dimens.xml”;找到styles.xml文件,把
改为
预览图
源码
anim.xml
<?xml version="1.0" encoding="utf-8"?>
bigalpha.xml
<?xml version="1.0" encoding="utf-8"?>
smallalpha.xml
<?xml version="1.0" encoding="utf-8"?>
dimens.xml
16dp 16dp
MainActivity.java
1package com.example.slyarh.text;import android.animation.ObjectAnimator;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.Handler;import android.os.IBinder;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.KeyEvent;import android.view.View;import android.view.animation.LinearInterpolator;import android.widget.ImageView;import android.widget.SeekBar;import android.widget.TextView;import java.text.SimpleDateFormat;public class MainActivity extends AppCompatActivity { private TextView musicStatus, musicTime, musicTotal; private SeekBar seekBar; private ImageView btnPlayOrPause, btnStop, btnQuit; private SimpleDateFormat time = new SimpleDateFormat("mm:ss"); private boolean tag1 = false; private boolean tag2 = false; private MusicService musicService; private ArcDemo mArc; // 在Activity中调用 bindService 保持与 Service 的通信 private void bindServiceConnection() { Intent intent = new Intent(MainActivity.this, MusicService.class); startService(intent); bindService(intent, serviceConnection, this.BIND_AUTO_CREATE); } // 回调onServiceConnected 函数,通过IBinder 获取 Service对象,实现Activity与 Service的绑定 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { musicService = ((MusicService.MyBinder) (service)).getService(); Log.i("musicService", musicService + ""); musicTotal.setText(time.format(musicService.mediaPlayer.getDuration())); } @Override public void onServiceDisconnected(ComponentName name) { musicService = null; } }; // 通过 Handler 更新 UI 上的组件状态 public Handler handler = new Handler(); public Runnable runnable = new Runnable() { @Override public void run() { musicTime.setText(time.format(musicService.mediaPlayer.getCurrentPosition())); seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekBar.setMax(musicService.mediaPlayer.getDuration()); musicTotal.setText(time.format(musicService.mediaPlayer.getDuration())); handler.postDelayed(runnable, 200); } }; private void findViewById() { musicTime = (TextView) findViewById(R.id.MusicTime); musicTotal = (TextView) findViewById(R.id.MusicTotal); seekBar = (SeekBar) findViewById(R.id.MusicSeekBar); btnPlayOrPause = (ImageView) findViewById(R.id.BtnPlayorPause); btnStop = (ImageView) findViewById(R.id.BtnStop); btnQuit = (ImageView) findViewById(R.id.BtnQuit); musicStatus = (TextView) findViewById(R.id.MusicStatus); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findViewById(); bindServiceConnection(); //myListener(); ImageView imageView = (ImageView) findViewById(R.id.Image); final ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "rotation", 0f, 360.0f); animator.setDuration(10000); animator.setInterpolator(new LinearInterpolator()); animator.setRepeatCount(-1); seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser == true) { musicService.mediaPlayer.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) { } @Override public void onStopTrackingTouch(SeekBar seekBar) { } }); mArc = (ArcDemo) findViewById(R.id.view_arc); mArc.setOnSubItemClickListener(new ArcDemo.onSubItemClickListener() { @Override public void onItemClick(View view, int position) { if(position==5){ if (musicService.mediaPlayer != null) { seekBar.setProgress(musicService.mediaPlayer.getCurrentPosition()); seekBar.setMax(musicService.mediaPlayer.getDuration()); } // 由tag的变换来控制事件的调用 if (musicService.tag != true) { //btnPlayOrPause.setText("PAUSE"); musicStatus.setText("正在播放.."); musicService.playOrPause(); musicService.tag = true; btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.pause)); if (tag1 == false) { animator.start(); tag1 = true; } else { animator.resume(); } } else { //btnPlayOrPause.setText("PLAY"); musicStatus.setText("暂停播放.."); musicService.playOrPause(); animator.pause(); btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.play)); musicService.tag = false; } if (tag2 == false) { handler.post(runnable); tag2 = true; } } else if(position==6){ musicStatus.setText("停止播放.."); // btnPlayOrPause.setText("PLAY"); musicService.stop(); btnPlayOrPause.setImageDrawable(getResources().getDrawable(R.drawable.play)); animator.pause(); musicService.tag = false; } else if(position==7) exit(); } }); } // 停止服务时,必须解除绑定,写入btnQuit按钮中 public void exit(){ handler.removeCallbacks(runnable); unbindService(serviceConnection); Intent intent = new Intent(MainActivity.this, MusicService.class); stopService(intent); try { MainActivity.this.finish(); } catch (Exception e) {} } // 获取并设置返回键的点击事件 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { moveTaskToBack(false); return true; } return super.onKeyDown(keyCode, event); }}
activity_main.xml
1<?xml version="1.0" encoding="utf-8"?>
MusicService.java
1package com.example.slyarh.text;import android.app.Service;import android.content.Intent;import android.media.MediaPlayer;import android.os.Binder;import android.os.IBinder;public class MusicService extends Service { public MediaPlayer mediaPlayer=null; public boolean tag = false; public MusicService() { mediaPlayer = new MediaPlayer(); try { mediaPlayer.reset(); mediaPlayer = MediaPlayer.create(this, R.raw.lucky); mediaPlayer.seekTo(0); mediaPlayer.setLooping(true); stop(); } catch (Exception e) { e.printStackTrace(); } } // 通过 Binder 来保持 Activity 和 Service 的通信 public MyBinder binder = new MyBinder(); public class MyBinder extends Binder { MusicService getService() { return MusicService.this; } } public void playOrPause() { if (mediaPlayer.isPlaying()) { mediaPlayer.setLooping(true); mediaPlayer.pause(); } else { mediaPlayer.setLooping(true); mediaPlayer.start(); } } public void stop() { if (mediaPlayer != null) { mediaPlayer.stop(); mediaPlayer.setLooping(true); try { mediaPlayer.reset(); mediaPlayer = MediaPlayer.create(this, R.raw.lucky); mediaPlayer.seekTo(0); mediaPlayer.setLooping(true); } catch (Exception e) { e.printStackTrace(); } } } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public IBinder onBind(Intent intent) { return binder; }}
ArcDemo.java
package com.example.slyarh.text;import android.content.Context;import android.util.AttributeSet;import android.view.View;import android.view.ViewGroup;import android.view.animation.Animation;import android.view.animation.AnimationSet;import android.view.animation.AnimationUtils;import android.view.animation.RotateAnimation;import android.view.animation.TranslateAnimation;public class ArcDemo extends ViewGroup { private View mButton; private BStatus mBStatus = BStatus.STATUS_CLOSE; private onSubItemClickListener onListener; public enum BStatus { STATUS_OPEN, STATUS_CLOSE } //子菜单点击接口 public interface onSubItemClickListener { void onItemClick(View view, int position); } public void setOnSubItemClickListener(onSubItemClickListener mListener) { this.onListener = mListener; } public ArcDemo(Context context) { super(context);// this(context, null); } public ArcDemo(Context context, AttributeSet attrs) { super(context, attrs);// this(context, attrs, 0); } public ArcDemo(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int count = getChildCount(); for (int i = 0; i < count; i++) { measureChild(getChildAt(i), widthMeasureSpec, heightMeasureSpec); } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } //添加布局,就是所要显示的控件View @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (changed) { //主菜单按钮 onMainButton(); //子菜单按钮 onSubItemButton(); } } //获取主菜单按钮 private void onMainButton() { mButton = getChildAt(0); mButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { //主菜单动画 Animation rotateAnim = AnimationUtils.loadAnimation(getContext(), R.anim.anim); mButton.startAnimation(rotateAnim); //子菜单动画 subItemAnim(); } }); int l, t, r = 0, b = 0; int mWidth = mButton.getMeasuredWidth(); int mHeight = mButton.getMeasuredHeight(); l = getMeasuredWidth() - mWidth; t = getMeasuredHeight() - mHeight; mButton.layout(l, t, getMeasuredWidth(), getMeasuredHeight()); } //获取子菜单按钮 private void onSubItemButton() { int count = getChildCount(); for (int i = 0; i < count - 1; i++) { View childView = getChildAt(i + 1); //开始时不呈现子菜单 childView.setVisibility(View.GONE); int radius = 350; int cl, ct, cr, cb; cr = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i)); cb = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i)); int cWidth = childView.getMeasuredWidth(); int cHeight = childView.getMeasuredHeight(); cl = getMeasuredWidth() - cWidth - cr; ct = getMeasuredHeight() - cHeight - cb; //layout(l,t,r,b);前两参数决定位置,后两参数决定大小 //参数(1,t)为View控件的左上角坐标 // (r-l,b-t)为View控件大小,r-l为控件宽度,b-t为控件高度 childView.layout(cl, ct, getMeasuredWidth() - cr, getMeasuredHeight() - cb); } } //子菜单散开回笼动画 public void subItemAnim() { int count = getChildCount(); for (int i = 0; i < count - 1; i++) { final View cView = getChildAt(i + 1); //点击主菜单后,子菜单就立刻呈现,否则后面的动画无法完成 cView.setVisibility(VISIBLE); int radius = 350; int l, t, r, d; r = (int) (radius * Math.sin(Math.PI / 2 / (count - 2) * i)); d = (int) (radius * Math.cos(Math.PI / 2 / (count - 2) * i));// int cWidth = cView.getMeasuredWidth();// int cHeight = cView.getMeasuredHeight();//// l = getMeasuredWidth() - cWidth - r;// t = getMeasuredHeight() - cHeight - d; AnimationSet set = new AnimationSet(true); Animation tranAnim = null; if (mBStatus == BStatus.STATUS_CLOSE) { //散开动画 tranAnim = new TranslateAnimation(r, 0, d, 0); cView.setClickable(true); cView.setFocusable(true); } else { //回笼动画 tranAnim = new TranslateAnimation(0, r, 0, d); cView.setClickable(false); cView.setFocusable(false); } tranAnim.setDuration(300);// tranAnim.setFillAfter(true); //让最后一帧的动画不消失 tranAnim.setStartOffset(100 * i / count); tranAnim.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if (mBStatus == BStatus.STATUS_CLOSE) { cView.setVisibility(GONE); } } @Override public void onAnimationRepeat(Animation animation) { } }); Animation rotateAnim = new RotateAnimation( 0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); rotateAnim.setDuration(300);// rotateAnim.setFillAfter(false); set.addAnimation(rotateAnim); set.addAnimation(tranAnim); cView.startAnimation(set); //散开后子菜单的点击监听事件 final int pos = i + 1; cView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (onListener != null) { onListener.onItemClick(cView, pos); } //散开后点击子菜单动画 subItemClickAnim(pos - 1); changStatus(); } }); } changStatus(); } //监听子菜单状态改变 private void changStatus() { mBStatus = (mBStatus == BStatus.STATUS_CLOSE ? BStatus.STATUS_OPEN : BStatus.STATUS_CLOSE); } //散开后点击子菜单动画 private void subItemClickAnim(int pos) { int count = getChildCount(); for (int i = 0;i
✎﹏﹏₯㎕《晴天》从出生那年就飘着...﹍﹍﹍﹍﹍﹍
更多相关文章
- Android最佳实践之Material Design
- android studio 3.5.1 使用第三方.so 库
- android_studio连接夜神模拟器
- 【Android】树形菜单、扩展下拉菜单android.widget.ExpandableLi
- Android(安卓)Property Animation 介绍(一)
- Android按钮按下时和弹起时的颜色设置
- Android(安卓)Studio Property属性动画
- Android(安卓)上下文菜单 ContextMenu
- android ContextMenu 上下文菜单示例