我们大家平时长时间打代码的时候肯定会感到疲惫和乏味,这个时候一边播放自己喜欢的音乐,一边继续打代码,心情自然也愉快很多。音乐带给人的听觉享受是无可比拟的,动听的音乐可以愉悦人的身心,让人更加积极地去热爱生活。大家平常应该会用QQ音乐、网易云音乐或者酷狗音乐等音乐APP来听歌,想不想拥有属于自己的音乐播放器。那么接下来就教大家如何用Android Studio自己制作一个音乐播放器APP。



项目目录

  • 一、项目概述
    • 1、需求分析
    • 2、设计分析
    • 3、资源文件分析
  • 二、开发环境
  • 三、准备工具
  • 四、详细设计
    • 1、搭建主界面布局
    • 2、创建服务类
      • 2.1、服务概述
      • 2.2、服务的创建
      • 2.3、服务的启动方式
      • 2.4、服务的生命周期
    • 3、搭建音乐播放界面布局
    • 4、搭建音乐列表界面布局
    • 5、搭建专辑界面布局
    • 6、导入资源文件
  • 五、项目效果
    • 1、创建模拟器
    • 2、运行演示
  • 六、项目总结
  • 七、源码下载
  • 八、升级优化

一、项目概述

1、需求分析

综合运用UI界面设计、数据存储、Activity(活动)、Service(服务)、MusicPlayer、ListView等知识,设计开发一款具有音乐列表的音乐播放器。

2、设计分析

整个项目包含五个类和五个布局文件:

其中frag1、frag2为java文件,
MusicActivity为Activity文件,
MusicService为Service文件,
MainActivity为项目创建时自动生成的Activity文件。

activity_main为MainActivity的布局文件,显示运行APP时的主界面。
activity_music为MusicActivity的布局文件,显示音乐播放器界面。
music_list和item_layout一起组成frag1的布局文件,
就是音乐列表界面(打开APP默认显示音乐列表界面)。
frag2_layout就是frag2的布局文件,主要显示的是专辑封面图片。

3、资源文件分析

在res文件夹下创建了raw文件夹,放了三首音乐文件,在drawable文件夹中粘贴了音乐封面图片bg.jpg和播放器背景图片music_bg.jpg,还有背景选择器的btn_bg_selector.xml文件,如图所示:

二、开发环境

三、准备工具

1、选择几首自己下载好的音乐文件,命名为music0、music1、music2等,这里歌曲都要是mp3类型的,数量随意。歌曲名的下标是从0开始的,因为代码中我设置的url地址是从0开始的,否则会闪退。

2、选择每首歌对应的歌手图片,剪成圆形并且保存好,命名为music0、music1、music2等。

图片一定要剪成圆形,椭圆会影响运行效果,导致闪退,如果不太清楚图片如何剪成圆形,可以看这篇博客:如何将图片剪成圆形,也非常简单。

3、准备一张音乐播放器的背景图片,命名为music_bg,再找一张图片用作专辑图片,命名为bg。

四、详细设计

1、搭建主界面布局

首先打开Android Studio,并新建一个工程,File——>New——>New Project——>Empty Project,工程名称叫做Music_List。

包名自己随意设定,这里博主用的是zj.dzh;工程文件的保存路径要修改一下,不要放在C盘,博主这里选择的是放在E盘的一个Projects文件夹中,养成项目统一放在英文路径下的好习惯。

最后选择API 18:Android 4.3,因为这样它就拥有了99.5%的跨平台性(兼容性非常好),因为它版本很低,基本上模拟器API版本都是高于20的,所以这个软件可以运行其他各种设备上。点击Finish完成创建。

设计一个app的时候,一定要先设计layout文件,再设计java文件,因为布局有了,才能在上面进行代码的编写。我们来看一下activity_main布局文件,它主要显示主界面。什么是主界面,就是一个APP运行后默认显示的界面。

最外层用的是LinearLayout线性布局,然后设置的是垂直排列。里面放了两个小的LinearLayout,分别是最上面的一个TextView,内容设置的是“我喜欢”,接着第二个小的LinearLayout放两个水平的TextView控件,内容显示的是“歌曲”和“专辑”。

最下面的剩余空间全部给了Fragment,它的id是content,这里不知道Fragment没关系,反正就晓得它和TextView一样可以显示内容就行。效果如图:

Fragment是一种可以嵌入在活动中的UI片段,能够让程序更加合理和充分地利用大屏幕的空间,出现的初衷是为了适应大屏幕的平板电脑,可以将其看成一个小型Activity,又称作Activity片段。


完整代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"android:orientation="vertical"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"android:text="我喜欢"android:textSize="35dp"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><TextViewandroid:id="@+id/menu1"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"android:text="歌曲"android:textSize="25dp"/><TextViewandroid:id="@+id/menu2"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:gravity="center"android:text="专辑"android:textSize="25dp"/></LinearLayout><FrameLayoutandroid:id="@+id/content"android:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="9"></FrameLayout></LinearLayout>

然后回到我们的Activity文件。MainActivity类是整个工程的主类,首先创建需要用到的控件,然后绑定控件,再设置监听器,底部导航栏设置的是两个菜单文件:frag1(歌曲菜单)和frag2(专辑菜单),默认情况下展示frag1歌曲菜单,点击切换显示frag2专辑菜单。代码如下:

package zj.dzh.music_list;import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;import android.os.Bundle;
import android.view.View;
import android.widget.TextView;public class MainActivity extends AppCompatActivity implements View.OnClickListener {//创建需要用到的控件的变量private TextView tv1,tv2;private FragmentManager fm;private FragmentTransaction ft;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//绑定控件tv1=(TextView)findViewById(R.id.menu1);tv2=(TextView)findViewById(R.id.menu2);//设置监听器,固定写法tv1.setOnClickListener(this);tv2.setOnClickListener(this);//若是继承FragmentActivity,fm=getFragmentManger();fm=getSupportFragmentManager();//fm可以理解为Fragment显示的管理者,ft就是它的改变者ft=fm.beginTransaction();//默认情况下就显示frag1ft.replace(R.id.content,new frag1());//提交改变的内容ft.commit();}@Override//控件的点击事件public void onClick(View v){ft=fm.beginTransaction();//切换选项卡switch (v.getId()){case R.id.menu1:ft.replace(R.id.content,new frag1());break;case R.id.menu2:ft.replace(R.id.content,new frag2());break;default:break;}ft.commit();}
}

2、创建服务类

2.1、服务概述

2.2、服务的创建


创建MusicService文件,右击包名——>New——>Service——>Service,如图:

命名为MusicService,然后Finish。

2.3、服务的启动方式

2.4、服务的生命周期


MusicService代码:

package zj.dzh.music_list;import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;import java.util.Timer;
import java.util.TimerTask;
//这是一个Service服务类
public class MusicService extends Service {//声明一个MediaPlayer引用private MediaPlayer player;//声明一个计时器引用private Timer timer;//构造函数public MusicService() {}@Overridepublic  IBinder onBind(Intent intent){return new MusicControl();}@Overridepublic void onCreate(){super.onCreate();//创建音乐播放器对象player=new MediaPlayer();}//添加计时器用于设置音乐播放器中的播放进度条public void addTimer(){//如果timer不存在,也就是没有引用实例if(timer==null){//创建计时器对象timer=new Timer();TimerTask task=new TimerTask() {@Overridepublic void run() {if (player==null) return;int duration=player.getDuration();//获取歌曲总时长int currentPosition=player.getCurrentPosition();//获取播放进度Message msg= MusicActivity.handler.obtainMessage();//创建消息对象//将音乐的总时长和播放进度封装至bundle中Bundle bundle=new Bundle();bundle.putInt("duration",duration);bundle.putInt("currentPosition",currentPosition);//再将bundle封装到msg消息对象中msg.setData(bundle);//最后将消息发送到主线程的消息队列MusicActivity.handler.sendMessage(msg);}};//开始计时任务后的5毫秒,第一次执行task任务,以后每500毫秒(0.5s)执行一次timer.schedule(task,5,500);}}//Binder是一种跨进程的通信方式class MusicControl extends Binder{public void play(int i){//String pathUri uri=Uri.parse("android.resource://"+getPackageName()+"/raw/"+"music"+i);try{//重置音乐播放器player.reset();//加载多媒体文件player=MediaPlayer.create(getApplicationContext(),uri);player.start();//播放音乐addTimer();//添加计时器}catch(Exception e){e.printStackTrace();}}//下面的暂停继续和退出方法全部调用的是MediaPlayer自带的方法public void pausePlay(){player.pause();//暂停播放音乐}public void continuePlay(){player.start();//继续播放音乐}public void seekTo(int progress){player.seekTo(progress);//设置音乐的播放位置}}//销毁多媒体播放器@Overridepublic void onDestroy(){super.onDestroy();if(player==null) return;if(player.isPlaying()) player.stop();//停止播放音乐player.release();//释放占用的资源player=null;//将player置为空}
}

3、搭建音乐播放界面布局

右击包名,新建一个Activity,命名为MusicActivity,点击Finish,它会生成一个activity_music文件,用来显示音乐播放界面,如图所示:

(1)MusicActivity类:通过onClick方法控制着音乐的播放、暂停、继续播放和退出功能。它和MusicService进行绑定连接。在音乐播放时显示歌曲总时长,还有歌曲当前播放时长,控制歌曲进度条的移动。代码如下:

package zj.dzh.music_list;import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;import android.animation.ObjectAnimator;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;import static java.lang.Integer.parseInt;public class MusicActivity extends AppCompatActivity implements View.OnClickListener{//进度条private static SeekBar sb;private static TextView tv_progress,tv_total,name_song;//动画private ObjectAnimator animator;private MusicService.MusicControl musicControl;private String name;private Intent intent1,intent2;private MyServiceConn conn;//记录服务是否被解绑,默认没有private boolean isUnbind =false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_music);//获取从frag1传来的信息intent1=getIntent();init();}private void init(){//进度条上小绿点的位置,也就是当前已播放时间tv_progress=(TextView)findViewById(R.id.tv_progress);//进度条的总长度,就是总时间tv_total=(TextView)findViewById(R.id.tv_total);//进度条的控件sb=(SeekBar)findViewById(R.id.sb);//歌曲名显示的控件name_song=(TextView)findViewById(R.id.song_name);//绑定控件的同时设置点击事件监听器findViewById(R.id.btn_play).setOnClickListener(this);findViewById(R.id.btn_pause).setOnClickListener(this);findViewById(R.id.btn_continue_play).setOnClickListener(this);findViewById(R.id.btn_exit).setOnClickListener(this);name=intent1.getStringExtra("name");name_song.setText(name);//创建一个意图对象,是从当前的Activity跳转到Serviceintent2=new Intent(this,MusicService.class);conn=new MyServiceConn();//创建服务连接对象bindService(intent2,conn,BIND_AUTO_CREATE);//绑定服务//为滑动条添加事件监听,每个控件不同果然点击事件方法名都不同sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {//这一行注解是保证API在KITKAT以上的模拟器才能顺利运行,也就是19以上@RequiresApi(api = Build.VERSION_CODES.KITKAT)@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {//进当滑动条到末端时,结束动画if (progress==seekBar.getMax()){animator.pause();//停止播放动画}}@Override//滑动条开始滑动时调用public void onStartTrackingTouch(SeekBar seekBar) {}@Override//滑动条停止滑动时调用public void onStopTrackingTouch(SeekBar seekBar) {//根据拖动的进度改变音乐播放进度int progress=seekBar.getProgress();//获取seekBar的进度musicControl.seekTo(progress);//改变播放进度}});//声明并绑定音乐播放器的iv_music控件ImageView iv_music=(ImageView)findViewById(R.id.iv_music);String position= intent1.getStringExtra("position");//praseInt()就是将字符串变成整数类型int i=parseInt(position);iv_music.setImageResource(frag1.icons[i]);//rotation和0f,360.0f就设置了动画是从0°旋转到360°animator=ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);animator.setDuration(10000);//动画旋转一周的时间为10秒animator.setInterpolator(new LinearInterpolator());//匀速animator.setRepeatCount(-1);//-1表示设置动画无限循环}//handler机制,可以理解为线程间的通信,我获取到一个信息,然后把这个信息告诉你,就这么简单public static Handler handler=new Handler(){//创建消息处理器对象//在主线程中处理从子线程发送过来的消息@Overridepublic void handleMessage(Message msg){Bundle bundle=msg.getData();//获取从子线程发送过来的音乐播放进度//获取当前进度currentPosition和总时长durationint duration=bundle.getInt("duration");int currentPosition=bundle.getInt("currentPosition");//对进度条进行设置sb.setMax(duration);sb.setProgress(currentPosition);//歌曲是多少分钟多少秒钟int minute=duration/1000/60;int second=duration/1000%60;String strMinute=null;String strSecond=null;if(minute<10){//如果歌曲的时间中的分钟小于10strMinute="0"+minute;//在分钟的前面加一个0}else{strMinute=minute+"";}if (second<10){//如果歌曲中的秒钟小于10strSecond="0"+second;//在秒钟前面加一个0}else{strSecond=second+"";}//这里就显示了歌曲总时长tv_total.setText(strMinute+":"+strSecond);//歌曲当前播放时长minute=currentPosition/1000/60;second=currentPosition/1000%60;if(minute<10){//如果歌曲的时间中的分钟小于10strMinute="0"+minute;//在分钟的前面加一个0}else{strMinute=minute+" ";}if (second<10){//如果歌曲中的秒钟小于10strSecond="0"+second;//在秒钟前面加一个0}else{strSecond=second+" ";}//显示当前歌曲已经播放的时间tv_progress.setText(strMinute+":"+strSecond);}};//用于实现连接服务,比较模板化,不需要详细知道内容class MyServiceConn implements ServiceConnection{@Overridepublic void onServiceConnected(ComponentName name, IBinder service){musicControl=(MusicService.MusicControl) service;}@Overridepublic void onServiceDisconnected(ComponentName name){}}//判断服务是否被解绑private void unbind(boolean isUnbind){//如果解绑了if(!isUnbind){musicControl.pausePlay();//音乐暂停播放unbindService(conn);//解绑服务}}@RequiresApi(api = Build.VERSION_CODES.KITKAT)@Overridepublic void onClick(View v) {switch (v.getId()){case R.id.btn_play://播放按钮点击事件String position=intent1.getStringExtra("position");int i=parseInt(position);musicControl.play(i);animator.start();break;case R.id.btn_pause://暂停按钮点击事件musicControl.pausePlay();animator.pause();break;case R.id.btn_continue_play://继续播放按钮点击事件musicControl.continuePlay();animator.start();break;case R.id.btn_exit://退出按钮点击事件unbind(isUnbind);isUnbind=true;finish();break;}}@Overrideprotected void onDestroy(){super.onDestroy();unbind(isUnbind);//解绑服务}
}

(2)activity_music: 显示音乐播放器界面,包括图片转动,歌曲名传值,还有播放、暂停播放、继续播放和退出四个控制按钮。效果如图:

activity_music代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/music_bg"tools:context=".Music_Activity"android:gravity="center"android:orientation="vertical"><ImageViewandroid:id="@+id/iv_music"android:layout_width="240dp"android:layout_height="240dp"android:layout_gravity="center_horizontal"android:layout_margin="15dp"android:src="@drawable/music0"/><TextViewandroid:id="@+id/song_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="歌曲名"android:textSize="20sp"/><SeekBarandroid:id="@+id/sb"android:layout_width="match_parent"android:layout_height="wrap_content" /><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:paddingLeft="8dp"android:paddingRight="8dp"><TextViewandroid:id="@+id/tv_progress"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="00:00"/><TextViewandroid:id="@+id/tv_total"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="00:00"/></RelativeLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"><Buttonandroid:id="@+id/btn_play"android:layout_width="0dp"android:layout_height="40dp"android:layout_margin="8dp"android:layout_weight="1"android:background="@drawable/btn_bg_selector"android:text="播放音乐"/><Buttonandroid:id="@+id/btn_pause"android:layout_width="0dp"android:layout_height="40dp"android:layout_margin="8dp"android:layout_weight="1"android:background="@drawable/btn_bg_selector"android:text="暂停播放"/><Buttonandroid:id="@+id/btn_continue_play"android:layout_width="0dp"android:layout_height="40dp"android:layout_margin="8dp"android:layout_weight="1"android:background="@drawable/btn_bg_selector"android:text="继续播放"/><Buttonandroid:id="@+id/btn_exit"android:layout_width="0dp"android:layout_height="40dp"android:layout_margin="8dp"android:layout_weight="1"android:background="@drawable/btn_bg_selector"android:text="退出"/></LinearLayout></LinearLayout>

(3)右击drawable文件夹,New——>Drawable Resource File,命名为btn_bg_selector,如图:

该文件为按钮颜色选择器,是当播放等按钮按下的时候变成灰色,未按下显示白色。代码如下:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"><item android:state_pressed="true"><shape android:shape="rectangle"><corners android:radius="10dp"/><solid android:color="#d4d4d4"/></shape></item><item android:state_pressed="false"><shape android:shape="rectangle"><corners android:radius="10dp"/><solid android:color="#ffffff"/></shape></item>
</selector>

4、搭建音乐列表界面布局

右击包名——>New——>Java Class,命名为frag1,点击OK。如图:

(1)frag1类:显示歌曲列表,手机模拟器运行出来的默认界面,就是将歌曲名、歌曲图片以列表的形式显示出来,注释很详细,代码如下:

package zj.dzh.music_list;import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;import androidx.fragment.app.Fragment;public class frag1 extends Fragment {private View view;//创建歌曲的String数组和歌手图片的int数组public String[] name={"邓紫棋——光年之外","蔡健雅——红色高跟鞋","Taylor Swift——Love Story"};public static int[] icons={R.drawable.music0,R.drawable.music1,R.drawable.music2};@Overridepublic View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){//绑定布局,只不过这里是用inflate()方法view=inflater.inflate(R.layout.music_list,null);//创建listView列表并且绑定控件ListView listView=view.findViewById(R.id.lv);//实例化一个适配器MyBaseAdapter adapter=new MyBaseAdapter();//列表设置适配器listView.setAdapter(adapter);//列表元素的点击监听器listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//创建Intent对象,参数就是从frag1跳转到MusicActivityIntent intent=new Intent(frag1.this.getContext(), MusicActivity.class);//将歌曲名和歌曲的下标存入Intent对象intent.putExtra("name",name[position]);intent.putExtra("position",String.valueOf(position));//开始跳转startActivity(intent);}});return view;}//这里是创建一个自定义适配器,可以作为模板class MyBaseAdapter extends BaseAdapter{@Overridepublic int getCount(){return  name.length;}@Overridepublic Object getItem(int i){return name[i];}@Overridepublic long getItemId(int i){return i;}@Overridepublic View getView(int i ,View convertView, ViewGroup parent) {//绑定好VIew,然后绑定控件View view=View.inflate(frag1.this.getContext(),R.layout.item_layout,null);TextView tv_name=view.findViewById(R.id.item_name);ImageView iv=view.findViewById(R.id.iv);//设置控件显示的内容,就是获取的歌曲名和歌手图片tv_name.setText(name[i]);iv.setImageResource(icons[i]);return view;}}}

(2)右击layout文件夹——>New———>Layout Resource File,新建两个layout文件,分别命名为music_list和item_layout,这两个布局文件和frag1对应,显示歌曲列表。如图所示:

music_list:歌曲列表布局文件,和QQ好友列表功能相同,垂直显示多条记录。效果如图:

music_list代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><ListViewandroid:id="@+id/lv"android:layout_width="match_parent"android:layout_height="wrap_content"/></LinearLayout>

item_layout: 就是条目布局,和上面的music_list列表一起组合使用,它就是相当于列表中每一行的布局,布局效果如图:

item_layout代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="16dp"><ImageViewandroid:id="@+id/iv"android:layout_width="40dp"android:layout_height="40dp"android:layout_centerVertical="true"/><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_toRightOf="@+id/iv"android:layout_centerVertical="true"><TextViewandroid:id="@+id/item_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="歌曲"android:textSize="15sp"android:textColor="#000000"/></RelativeLayout>
</RelativeLayout>

5、搭建专辑界面布局

右击包名,New——>Java Class,命名为frag2,点击OK。如图:
(1)frag2类:展示的封面专辑图片,在主界面点击专辑按钮跳转到此界面。代码如下:

package zj.dzh.music_list;import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;import androidx.fragment.app.Fragment;public class frag2 extends Fragment {//创建一个Viewprivate View zj;//显示布局public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {zj = inflater.inflate(R.layout.frag2_layout, null);return zj;}
}

(2)再新建一个layout文件,命名为frag2_layout,如图:

frag2_layout用来设置一个ImageView,显示专辑图片,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><ImageViewandroid:id="@+id/zj"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/bg"/></LinearLayout>

当然frag2可以自由发挥,比如说设置成歌手资料、MV列表或者排行榜等等。

6、导入资源文件

在res文件夹下新建一个raw文件夹,将刚刚准备好的音乐文件复制粘贴到raw文件夹中。对应的封面圆形图片、背景图片和专辑图片都复制粘贴到drawable中,这里博主只选择了三首歌曲和三张封面圆形图片,歌曲数量由大家自己设置,没有限制。

再次提醒下,注意命名哦;mp3歌曲文件在Android中打开是乱码,不用担心,也不需要打开它。


至此,完整的音乐播放器项目创建完成。

五、项目效果

1、创建模拟器

选择自己的模拟器运行,如果没有模拟器可以点击AVD,选择新建模拟器:

选择高于API 21的版本进行下载,如图:

2、运行演示

(1)运行手机模拟器,显示主界面:

(2)点击专辑选项卡:

(3)再选择歌曲选项卡,选择第一首歌《光年之外》并打开,跳转到音乐播放页面,歌手的封面图片显示在正中间,发现《光年之外》的歌名也传递过来了:


(4)点击播放音乐按钮,音乐开始播放,进度条开始滑动,图片开始旋转:

(5)点击暂停播放按钮,音乐停止播放,而且进度条停止滑动,图片也停止旋转:

(6)点击继续播放按钮,音乐继续播放,歌手图片也继续旋转:

(7)点击退出按钮,会退回到主界面:

(8)选择第二首歌《红色高跟鞋》并播放,这里进度条可以自由拖动,歌曲也会随之播放到对应位置:

(9)选择第三首歌《Love Story》并播放:

运行效果和功能很完整,至此完成了音乐播放器的实现,喜欢的朋友们可以自己动手做一下,放上自己喜欢的爱豆照片,还有喜欢的歌,体验感真的不要太好!

六、项目总结

这次音乐播放器工程,可以让大家熟练掌握Android程序开发的基本技术,涉及Android 基础知识、UI界面、数据存储、四大组件、网络编程、高级编程等。大家熟练掌握可以对以后的Android开发有很大的帮助。



七、源码下载

需要源码学习的同学可以关注我的微信公众号,回复:音乐播放器,即可获取源码。还有很多Android项目等你来学习。博主从头到尾详细讲述了该项目的搭建运行步骤,代码里面也有详细的注释,如果对你有帮助的话,记得三连支持下哦。下方还有最新的音乐播放器2.0版本。

八、升级优化

今天是2021.7.10,我又对这个项目进行了次更新,优化了播放器界面和上一首下一首功能,大家点击链接就可以直接跳转进行学习:

Android Studio如何实现音乐播放器(简单易上手)相关推荐

  1. Android Studio如何实现音乐播放器

    Android Studio如何实现音乐播放器 今天跟着大佬的步骤实现了一个和老师讲的不一样的简易音乐播放器,超级赞!再完善和改一下主题适合用作自己的音乐播放器. 原贴: Android Studio ...

  2. 基于Android的MediaPlayer的音乐播放器的封装

    基于Android的MediaPlayer的音乐播放器的封装 使用过android原生的mediaplayer来做音频播放的同学们,肯定是经历过一些痛苦的,因为android提供了一个状态机,确实这个 ...

  3. Android应用开发--MP3音乐播放器Service实现

    Android应用开发--MP3音乐播放器Service实现 2013年5月29日简.美音乐播放器开发记录 让网友们久等啦,关于简.美音乐播放器的开发,最重要的Service类总算是要发博了.关于An ...

  4. Android应用开发--MP3音乐播放器滚动歌词实现

    Android应用开发--MP3音乐播放器滚动歌词实现 2013年6月2日  简.美音乐播放器开发记录 -----前话 有网友给我博客评论说,让我借鉴好的Android代码,代码贴出来的时候最好整体先 ...

  5. Android studio怎么实现swf播放器

    使用Android studio 怎么实现swf播放器 比较着急 求

  6. Android应用开发 MP3音乐播放器滚动歌词实现

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Andr ...

  7. Android应用开发--MP3音乐播放器代码实现(一)

    Android应用开发--MP3音乐播放器代码实现(一) 需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1. 从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3I ...

  8. Android应用开发--MP3音乐播放器代码实现(二)

    2013年5月25日 简.美音乐播放器开发 小巫在这里罗列这个播放器已经实现的功能: 1.   自动显示音乐列表 2.   点击列表播放音乐 3.   长按列表弹出对话框 4.   暂停音乐 5.   ...

  9. 玩转Openwrt(二) — 配合Android手机打造无线音乐播放器

    前一篇文章大概介绍了刷入带ADSL驱动的openwrt以及简单的配置,这次就总结下一个好玩的应用,使用android手机+mpd打造一台无线音乐播放器. 所需装备: DB120或者RG100A或者其它 ...

最新文章

  1. Swift之深入解析可选链的功能和使用
  2. c#如何使用反射去创建一个委托_【自学C#】|| 笔记 37 创建线程
  3. ElasticSearch Java Api(一) -创建索引
  4. windows 下安装Python easy_install 和pip
  5. 大杂烩 -- 四种生成和解析XML文档的方法详解
  6. PLSQL存储过程中的内部存储过程
  7. 将阿拉伯数字转换成中文大写的好算法
  8. 默认参数和命名关键字参数(1)
  9. mysql8 修改密码_MySQL 8.0 解决:ERROR 2002、ERROR 1045 登陆问题
  10. MySql实战篇:写一个简单的存储过程,完成订单定时任务
  11. java对象中方法的存储原理_垃圾收集机制的基本原理及方法
  12. python九九乘法表代码及循环过程详解
  13. 【JS基础】JavaScript轮播图代码详解
  14. 怎么找网页源文件位置_无法查看网页的源文件该怎么办?
  15. 华为CANN训练营笔记——应用开发全流程 [5](with 代码版)
  16. Hyperledger caliper 安装记录
  17. 四.电影/综艺网站(包含搜索经验, 我的经验, 必看) 彻底帮你解决看电影/综艺的问题
  18. flyingsaucer转换多个html,使用flying-saucer 实现 html转pdf实现input框select,textarea
  19. 什么是容器编排及容器编排是怎么工作的?
  20. VMware中linux环境下oracle安装图文教程(一)

热门文章

  1. usb摄像头识别答题卡系统
  2. 系统集成项目管理工程师答题卡样式
  3. 计算机调剂怎么准备复试,终于明白考研调剂复试如何准备
  4. Maven及插件安装
  5. 俄罗斯套娃素数c语言解法,求俄罗斯套娃素数(BFS)
  6. 大数据技术周报第 001 期
  7. metasploit完整的使用流程包括meterpreter后渗透
  8. 分享一个神奇的空间数据库
  9. 什么是cobol语言,主要用来干嘛用的!(最近在其它做银行或证券的项目组常听到的关键字,搜到了一些基本概念)
  10. 【电气专业知识问答】问:高频开关直流充电电源结构、组成及性能特点是什么?