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 ”里,在</activity>后加一句<service android:name=".MusicService" android:enabled="true" android:exported="true" />
  • 在工程文件夹“ ..\app\src\main\res\values ”下,新建xml文档,命名为“dimens.xml”;找到styles.xml文件,把
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

    改为

    <style name="AppTheme" parent="Base.Theme.AppCompat.Light.DarkActionBar">

预览图


源码

anim.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"><rotateandroid:duration="300"android:fromDegrees="0"android:toDegrees="360"android:pivotX="50%"android:pivotY="50%"/>
</set>

bigalpha.xml

<?xml version="1.0" encoding="utf-8"?>
<!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><alphaandroid:duration="200"android:fromAlpha="1"android:toAlpha="0"/><scaleandroid:duration="200"android:fromXScale="1"android:fromYScale="1"android:toXScale="3"android:toYScale="3"android:pivotX="50%"android:pivotY="50%" />
</set>

smallalpha.xml

<?xml version="1.0" encoding="utf-8"?>
<!--android:fillAfter="true"得加,取动画结束后的最后一帧-->
<set xmlns:android="http://schemas.android.com/apk/res/android"android:fillAfter="true"><alphaandroid:duration="200"android:fromAlpha="1"android:toAlpha="0"/><scaleandroid:duration="200"android:fromXScale="1"android:fromYScale="1"android:toXScale="0"android:toYScale="0"android:pivotX="50%"android:pivotY="50%" />
</set>

dimens.xml

<resources><!-- Default screen margins, per the Android Design guidelines. --><dimen name="activity_horizontal_margin">16dp</dimen><dimen name="activity_vertical_margin">16dp</dimen>
</resources>

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() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {musicService = ((MusicService.MyBinder) (service)).getService();Log.i("musicService", musicService + "");musicTotal.setText(time.format(musicService.mediaPlayer.getDuration()));}@Overridepublic void onServiceDisconnected(ComponentName name) {musicService = null;}};//  通过 Handler 更新 UI 上的组件状态public Handler handler = new Handler();public Runnable runnable = new Runnable() {@Overridepublic 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);}@Overrideprotected 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() {@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {if (fromUser == true) {musicService.mediaPlayer.seekTo(progress);}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {}});mArc = (ArcDemo) findViewById(R.id.view_arc);mArc.setOnSubItemClickListener(new ArcDemo.onSubItemClickListener() {@Overridepublic 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) {}}//  获取并设置返回键的点击事件@Overridepublic 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"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><LinearLayoutandroid:layout_width="wrap_content"android:background="@drawable/bg1"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:background="#00000000"android:paddingBottom="16dp"android:paddingLeft="16dp"android:paddingRight="16dp"android:paddingTop="16dp"><ImageViewandroid:id="@+id/Image"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:src="@mipmap/img" /><!--显示歌曲状态--><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""android:id="@+id/MusicStatus"/><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_margin="5dp"android:gravity="center_horizontal"><!--显示当前进度--><TextViewandroid:id="@+id/MusicTime"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="00:00" /><SeekBarandroid:layout_width="230sp"android:layout_height="wrap_content"android:id="@+id/MusicSeekBar"android:layout_weight="1"android:max="100"android:layout_toRightOf="@+id/MusicTime"/><!--显示总进度--><TextViewandroid:id="@+id/MusicTotal"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="00:00"android:layout_toRightOf="@+id/MusicSeekBar"/></RelativeLayout></LinearLayout><RelativeLayoutandroid:layout_width="match_parent"android:background="#00000000"android:layout_height="match_parent"><com.example.slyarh.text.ArcDemoandroid:background="#00000000"android:id="@+id/view_arc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentStart="true"android:layout_alignParentTop="true"><RelativeLayoutandroid:id="@+id/main_menu"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/menu"></RelativeLayout><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><ImageViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"/><ImageViewandroid:id="@+id/BtnPlayorPause"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/play" /><ImageViewandroid:id="@+id/BtnStop"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/stop" /><ImageViewandroid:id="@+id/BtnQuit"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/exit" /></com.example.slyarh.text.ArcDemo></RelativeLayout></LinearLayout>
</FrameLayout>

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();}}}@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}@Overridepublic 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);}@Overrideprotected 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@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {if (mBStatus == BStatus.STATUS_CLOSE) {cView.setVisibility(GONE);}}@Overridepublic 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() {@Overridepublic 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<count-1;i++) {View cView = getChildAt(i+1);if(i == pos) {//变大,变透明cView.startAnimation(toBig());}else {//变小,变透明cView.startAnimation(toSmall());}cView.setClickable(false);cView.setFocusable(false);}}//变大,变透明private Animation toBig(){Animation big = AnimationUtils.loadAnimation(getContext(),R.anim.bigalpha);return big;}//变小,变透明private Animation toSmall(){Animation small = AnimationUtils.loadAnimation(getContext(),R.anim.smallalpha);return small;}//给ListView调用public boolean isOpen() {return mBStatus == BStatus.STATUS_OPEN;}}

✎﹏﹏₯㎕《晴天》从出生那年就飘着...﹍﹍﹍﹍﹍﹍

简易音乐播放器(Android Studio)相关推荐

  1. Android Studio简易音乐播放器设计作业

    Android Studio简易音乐播放器设计作业 实验成功展示 实验代码 MainActivity.java XML文件 class文件 利用BroadcastReceiver模拟音乐播放器,实现播 ...

  2. Android的媒体播放器------简易音乐播放器(详解)

    一.案例效果 二.欢迎界面的设计与功能 2.1 .案例效果 设计一个倒计时自动跳转的页面 2.2. 布局界面 activity_welcome.xml 参考代码: <?xml version=& ...

  3. 利用Broadcast及相关组件实现简易音乐播放器功能

    目录 前言 项目源码 准备工作 代码编写 页面布局 Service类的创建 主函数的编写 项目心得 前言 在Andriod Studio中使用Broadcast实现了简易音乐播放器的功能.可以进行播放 ...

  4. android 带记忆功能的播放器源码,【全开源可二开】带后台管理面板的在线音乐播放器Android应用APP源码...

    这是一款带后台管理面板的在线音乐播放器Android应用APP源码,可让您更快地构建在线和离线android音频播放器,代码全开源适合二次开发.该源码自带2个紫色和橙色主题(允许您添加更多主题),多语 ...

  5. JavaScript + Audio API自制简易音乐播放器(详细完整版、小白都能看懂)

    JavaScript + Audio API自制简易音乐播放器(详细完整版) ** 音乐播放器的功能清单如下: ** 1.点击暂停按钮,歌曲暂停 2.点击播放按钮,歌曲播放 3.单曲循环与取消单曲循环 ...

  6. MusicPlayer音乐播放器Android

    MusicPlayer音乐播放器Android [音频采集] 你可以使用手机进行现场录音,实现步骤如下: 第一步:在功能清单文件AndroidManifest.xml中添加音频刻录权限: <us ...

  7. html实现简易音乐播放器

    目标: 使用vue.js导包的形式做一个简单的音乐播放器,新手也很容易看懂. 内容: 1. 使用了flex实现响应式布局: 2. 使用min-width防止字体被压缩: 3. 使用computed计算 ...

  8. 单片机音乐播放器课程设计C语言,单片机课程设计简易音乐播放器

    单片机课程设计简易音乐播放器 论文题目:简易音乐播放器所属系部:电子工程系 指导教师: 学生姓名: 学 号: 专 业: 电子信息工程技术 题目: 简易音乐播放器任务与要求:本设计以 MCS-51 系列 ...

  9. 【毕业设计】28-基于单片机的音乐播放器简易音乐播放器设计(原理图+源代码+仿真工程+答辩PPT+答辩论文)

    typora-root-url: ./ [毕业设计]28-基于单片机的音乐播放器简易音乐播放器设计(原理图+源代码+仿真工程+答辩PPT+答辩论文) 文章目录 typora-root-url: ./ ...

  10. 【微信小程序】简易音乐播放器,进度条拖拉、音乐的播放与暂停

    小程序简易音乐播放器实现 粗糙的页面设计: wxml部分: <view class="test"><view class="img">& ...

最新文章

  1. Elasticsearch本地 docker-compose 安装
  2. activiti自己定义流程之整合(五):启动流程时获取自己定义表单
  3. Linux的shell scripts的shell脚本练习
  4. Qt/Qte/Qtopia三者的区别
  5. @Transcational特性
  6. keepalive日志_12.日志收集项目-数据流图以及nginx安装
  7. [CLR via C#]16. 数组
  8. SQL Server2008数据库的维护 (第四部分)
  9. 首发Android 13!谷歌Pixel 7 Pro渲染图曝光:后置相机模组吸睛
  10. 机器学习与计算机视觉(绘图)
  11. 欺骗神经网络_可以欺骗神经网络吗?
  12. iATKOS v7硬盘安装教程(硬盘助手+变色龙安装版)
  13. Linux dstat 监控工具
  14. 超酷汇编教程-- 简明x86汇编语言教程(1)
  15. 计算机二级C语言怎么过
  16. 如何在win7旗舰版下运行汇编的debug、masm、link等
  17. (转)浅谈拉布拉多中值定理
  18. P2P技术软件Murder分发大文件
  19. 嵌入式的优势在哪里?
  20. Ubuntu14.04安装calamari

热门文章

  1. spring boot新闻管理系统 毕业设计源码211113
  2. 港科喜讯 | 香港科大校长史维教授获法国政府颁授勋章
  3. 有效 360 度反馈系统的关键
  4. 1分钟解决 微信小程序 iPhone 11、iPhoneX 底部安全区域(底部小黑条)适配
  5. 海思开发板hi3559移植带opengl的qt并成功运行血泪史
  6. ubuntu 系统狠慢 或者很卡的原因
  7. Thinkphp3.2 PHPMailer 发送 QQ邮箱 163邮箱
  8. 2014儒豹浏览器的前行之路
  9. 【架构】大数据风控数据系统架构
  10. 关于将EXCEL文件导入到MYSQL数据库的一些方法