目录
一、引言
视频效果展示:
1.启动页效果
2.登录页效果
3.注册页效果
4.歌曲列表页效果
5.播放页效果
二、详细设计
1.登陆注册功能
2.音乐列表页面
2.音乐播放功能
三、源码获取
一、引言
Android初学者开发第一个完整的实例项目应该就属《音乐播放器》了,项目包含SQLlit数据库的使用、listview、Fragment、等。话不多说先上成品:
视频效果展示:
Android Studio 音乐播放器
图片效果展示:
1.启动页效果 |
2.登录页效果 |
3.注册页效果 |
4.歌曲列表页效果 |
5.播放页效果 |
二、详细设计
1.登陆注册功能
用户进行注册数据使用SQLite存储,用户登录时根据数据库的内容来核对用户名和密码是否正确。
Login.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns: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"android:background="#f9d7e7"tools:context=".Login.LoginActivity"><ImageViewandroid:id="@+id/imageView3"android:layout_width="200dp"android:layout_height="150dp"android:layout_marginTop="24dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/logo1" /><Viewandroid:id="@+id/view2"android:layout_width="0dp"android:layout_height="320dp"android:layout_marginTop="24dp"android:background="@drawable/login_view"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintStart_toStartOf="@+id/guideline3"app:layout_constraintTop_toBottomOf="@+id/imageView3" /><Buttonandroid:id="@+id/login_button"android:layout_width="250dp"android:layout_height="55dp"android:layout_marginBottom="32dp"android:background="@drawable/login"android:text="立 即 登 录 "android:textColor="#fff"android:textSize="24sp"app:layout_constraintBottom_toBottomOf="@+id/view2"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintStart_toStartOf="@+id/view2" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.9" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.1" /><Viewandroid:id="@+id/view3"android:layout_width="0dp"android:layout_height="45dp"android:layout_marginTop="40dp"android:background="@drawable/login_count"app:layout_constraintEnd_toEndOf="@+id/login_button"app:layout_constraintStart_toStartOf="@+id/login_button"app:layout_constraintTop_toTopOf="@+id/view2" /><Viewandroid:id="@+id/view4"android:layout_width="0dp"android:layout_height="45dp"android:layout_marginTop="24dp"android:background="@drawable/login_count"app:layout_constraintEnd_toEndOf="@+id/login_button"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="@+id/login_button"app:layout_constraintTop_toBottomOf="@+id/view3" /><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="24dp"android:text="忘 记 密 码"app:layout_constraintStart_toStartOf="@+id/view4"app:layout_constraintTop_toBottomOf="@+id/view4" /><TextViewandroid:id="@+id/login_register"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="立 即 注 册"app:layout_constraintBottom_toBottomOf="@+id/textView"app:layout_constraintEnd_toEndOf="@+id/view4"app:layout_constraintTop_toTopOf="@+id/textView" /><ImageViewandroid:id="@+id/imageView"android:layout_width="20dp"android:layout_height="20dp"app:layout_constraintBottom_toBottomOf="@+id/view4"app:layout_constraintEnd_toEndOf="@+id/imageView4"app:layout_constraintTop_toTopOf="@+id/view4"app:srcCompat="@drawable/mima" /><ImageViewandroid:id="@+id/imageView4"android:layout_width="20dp"android:layout_height="20dp"android:layout_marginStart="16dp"app:layout_constraintBottom_toBottomOf="@+id/view3"app:layout_constraintStart_toStartOf="@+id/view3"app:layout_constraintTop_toTopOf="@+id/view3"app:srcCompat="@drawable/zhanghao" /><Viewandroid:id="@+id/view5"android:layout_width="100dp"android:layout_height="1dp"android:layout_marginTop="40dp"android:background="#fff"app:layout_constraintStart_toStartOf="@+id/guideline3"app:layout_constraintTop_toBottomOf="@+id/view2" /><Viewandroid:id="@+id/view6"android:layout_width="100dp"android:layout_height="1dp"android:background="#fff"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintTop_toTopOf="@+id/view5" /><TextViewandroid:id="@+id/textView3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="其它方式登陆"android:textColor="#fff"app:layout_constraintBottom_toBottomOf="@+id/view5"app:layout_constraintEnd_toStartOf="@+id/view6"app:layout_constraintStart_toEndOf="@+id/view5"app:layout_constraintTop_toTopOf="@+id/view5" /><ImageViewandroid:id="@+id/imageView6"android:layout_width="30dp"android:layout_height="30dp"app:layout_constraintBottom_toBottomOf="@+id/imageView5"app:layout_constraintEnd_toStartOf="@+id/imageView7"app:layout_constraintStart_toEndOf="@+id/imageView5"app:layout_constraintTop_toTopOf="@+id/imageView5"app:srcCompat="@drawable/qq" /><ImageViewandroid:id="@+id/imageView5"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginStart="70dp"android:layout_marginTop="24dp"app:layout_constraintStart_toStartOf="@+id/guideline3"app:layout_constraintTop_toBottomOf="@+id/view5"app:srcCompat="@drawable/weixin" /><ImageViewandroid:id="@+id/imageView7"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="70dp"app:layout_constraintBottom_toBottomOf="@+id/imageView6"app:layout_constraintEnd_toStartOf="@+id/guideline2"app:layout_constraintTop_toTopOf="@+id/imageView6"app:srcCompat="@drawable/weibo" /><EditTextandroid:id="@+id/user"android:layout_width="190dp"android:layout_height="0dp"android:layout_marginStart="5dp"android:ems="10"android:background="#eff4f2"android:inputType="textPersonName"android:hint="请输入账号"app:layout_constraintBottom_toBottomOf="@+id/view3"app:layout_constraintStart_toEndOf="@+id/imageView4"app:layout_constraintTop_toTopOf="@+id/view3" /><EditTextandroid:id="@+id/pass"android:layout_width="190dp"android:layout_height="0dp"android:layout_marginStart="5dp"android:ems="10"android:background="#eff4f2"android:inputType="textPassword"android:hint="请输入密码"app:layout_constraintBottom_toBottomOf="@+id/view4"app:layout_constraintStart_toEndOf="@+id/imageView"app:layout_constraintTop_toTopOf="@+id/view4"app:layout_constraintVertical_bias="0.0" /></androidx.constraintlayout.widget.ConstraintLayout>
Register.xml代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns: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"android:background="#f9d7e7"tools:context=".Register.RegisterActivity"><ImageViewandroid:id="@+id/imageView3"android:layout_width="200dp"android:layout_height="150dp"android:layout_marginTop="40dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/logo1" /><Viewandroid:id="@+id/view2"android:layout_width="0dp"android:layout_height="270dp"android:background="@drawable/login_view"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toStartOf="@+id/guideline4"app:layout_constraintHorizontal_bias="0.0"app:layout_constraintStart_toStartOf="@+id/guideline"app:layout_constraintTop_toTopOf="@+id/imageView3"app:layout_constraintVertical_bias="0.501" /><Viewandroid:id="@+id/view3"android:layout_width="250dp"android:layout_height="45dp"android:layout_marginTop="32dp"android:background="@drawable/login_count"app:layout_constraintEnd_toStartOf="@+id/guideline4"app:layout_constraintStart_toStartOf="@+id/view2"app:layout_constraintTop_toTopOf="@+id/view2" /><Viewandroid:id="@+id/view4"android:layout_width="0dp"android:layout_height="45dp"android:layout_marginTop="32dp"android:background="@drawable/login_count"app:layout_constraintEnd_toEndOf="@+id/view3"app:layout_constraintStart_toStartOf="@+id/view3"app:layout_constraintTop_toBottomOf="@+id/view3" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.1" /><androidx.constraintlayout.widget.Guidelineandroid:id="@+id/guideline4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"app:layout_constraintGuide_percent="0.9" /><ImageViewandroid:id="@+id/imageView"android:layout_width="20dp"android:layout_height="20dp"android:layout_marginStart="8dp"app:layout_constraintBottom_toBottomOf="@+id/view3"app:layout_constraintStart_toStartOf="@+id/view3"app:layout_constraintTop_toTopOf="@+id/view3"app:srcCompat="@drawable/mima" /><ImageViewandroid:id="@+id/imageView4"android:layout_width="20dp"android:layout_height="20dp"app:layout_constraintBottom_toBottomOf="@+id/view4"app:layout_constraintStart_toStartOf="@+id/imageView"app:layout_constraintTop_toTopOf="@+id/view4"app:srcCompat="@drawable/zhanghao" /><Buttonandroid:id="@+id/register_button"android:layout_width="250dp"android:layout_height="55dp"android:text="立 即 注 册"android:layout_marginBottom="32dp"android:background="@drawable/login"app:layout_constraintBottom_toBottomOf="@+id/view2"app:layout_constraintEnd_toEndOf="@+id/view2"app:layout_constraintHorizontal_bias="0.497"app:layout_constraintStart_toStartOf="@+id/view2" /><EditTextandroid:id="@+id/username_edittext"android:layout_width="190dp"android:layout_height="0dp"android:layout_marginStart="5dp"android:ems="10"android:hint="请输入账号"android:background="#eff4f2"android:inputType="textPersonName"app:layout_constraintBottom_toBottomOf="@+id/view3"app:layout_constraintStart_toEndOf="@+id/imageView"app:layout_constraintTop_toTopOf="@+id/view3" /><EditTextandroid:id="@+id/password_edittext"android:layout_width="190dp"android:layout_height="0dp"android:layout_marginStart="5dp"android:ems="10"android:hint="请输入密码"android:background="#eff4f2"android:inputType="textPassword"app:layout_constraintBottom_toBottomOf="@+id/view4"app:layout_constraintStart_toEndOf="@+id/imageView4"app:layout_constraintTop_toTopOf="@+id/view4" /></androidx.constraintlayout.widget.ConstraintLayout>
LoginActivity完整代码:
package com.example.music.Login;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import com.example.music.MainActivity;
import com.example.music.R;
import com.example.music.Register.RegisterActivity;
import com.example.music.Data.DatabaseHelper;public class LoginActivity extends AppCompatActivity {private TextView loginRegister;private EditText user;private EditText pass;private Button mLoginButton;private DatabaseHelper mDatabaseHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_login);user = findViewById(R.id.user);pass = findViewById(R.id.pass);mLoginButton = findViewById(R.id.login_button);loginRegister = findViewById(R.id.login_register);mDatabaseHelper = new DatabaseHelper(this);loginRegister.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);startActivity(intent);}});mLoginButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String username = user.getText().toString().trim();String password = pass.getText().toString().trim();if (username.isEmpty() || password.isEmpty()) {Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();return;}boolean result = mDatabaseHelper.checkUser(username, password);if (result) {Toast.makeText(getApplicationContext(), "登陆成功", Toast.LENGTH_SHORT).show();Intent intent = new Intent(LoginActivity.this, MainActivity.class);startActivity(intent);} else {Toast.makeText(getApplicationContext(), "账号或密码错误", Toast.LENGTH_SHORT).show();}}});}
}
RegisterActivity完整代码:
package com.example.music.Register;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import com.example.music.Login.LoginActivity;
import com.example.music.R;
import com.example.music.Data.DatabaseHelper;public class RegisterActivity extends AppCompatActivity {private EditText mUserNameEditText;private EditText mPasswordEditText;private Button registerButton;private DatabaseHelper mDatabaseHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_register);mUserNameEditText = findViewById(R.id.username_edittext);mPasswordEditText = findViewById(R.id.password_edittext);registerButton = findViewById(R.id.register_button);mDatabaseHelper = new DatabaseHelper(this);registerButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String username = mUserNameEditText.getText().toString().trim();String password = mPasswordEditText.getText().toString().trim();if (username.isEmpty() || password.isEmpty()) {Toast.makeText(getApplicationContext(), "请输入账号或密码", Toast.LENGTH_SHORT).show();return;}boolean result = mDatabaseHelper.insertData(username, password);if (result) {Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_SHORT).show();Intent intent = new Intent(RegisterActivity.this, LoginActivity.class);startActivity(intent);finish();} else {Toast.makeText(getApplicationContext(), "注册失败", Toast.LENGTH_SHORT).show();}}});}
}
2.音乐列表页面
主要用于音乐的显示以及点击对应的音乐跳转到对应的音乐播放页面。
Activity完整代码:
package com.example.music;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;import com.example.music.Music.MusicActivity;public class SongPage extends Fragment {//声明视图变量viewprivate View view;//在这里添加歌曲名public String[] songname = {"Innocence", "刚刚好","不用去猜"};private String[] name={"A R L","薛之谦","Jony J"};//在这里添加歌曲图片public static int[] icons = {R.drawable.img_01, R.drawable.img_02, R.drawable.img_03};@Overridepublic View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {view = inflater.inflate(R.layout.music_list, null);//1、创建并绑定列表ListView listView = view.findViewById(R.id.lv);//2、创建适配器对象MyBaseAdapter adapter = new MyBaseAdapter();//3、给列表设置适配器listView.setAdapter(adapter);//设置列表条目监听器listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {//创建Intent对象,启动音乐播放界面Intent intent = new Intent(SongPage.this.getContext(), MusicActivity.class);//将数据存入Intent对象,利用键值对intent.putExtra("name", name[position]);intent.putExtra("songname", songname[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.inflate(SongPage.this.getContext(), R.layout.item_music, null);TextView songName = view.findViewById(R.id.song_name);ImageView songPic = view.findViewById(R.id.song_pic);TextView name1=view.findViewById(R.id.name);songName.setText(songname[i]);name1.setText(name[i]);songPic.setImageResource(icons[i]);return view;}}}
相关的xml代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns: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="wrap_content"android:padding="15dp"><ImageViewandroid:id="@+id/song_pic"android:layout_width="86dp"android:layout_height="86dp"android:src="@drawable/img_01"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent" /><TextViewandroid:id="@+id/song_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="8dp"android:layout_marginTop="16dp"android:text="歌曲"android:textColor="#000"android:textSize="20sp"app:layout_constraintStart_toEndOf="@+id/song_pic"app:layout_constraintTop_toTopOf="@+id/song_pic" /><TextViewandroid:id="@+id/name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="8dp"android:text="歌曲"android:textColor="#000"android:textSize="14sp"app:layout_constraintStart_toStartOf="@+id/song_name"app:layout_constraintTop_toBottomOf="@+id/song_name" /><ImageViewandroid:id="@+id/song_enter"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="8dp"android:src="@drawable/song_play"app:layout_constraintBottom_toBottomOf="@+id/song_pic"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintTop_toTopOf="@+id/song_pic" /></androidx.constraintlayout.widget.ConstraintLayout>
2.音乐播放功能
用于播放音乐,对音乐进行暂停,上一首、下一首功能的实现。
具体MusicActivity代码:
public class MusicActivity extends AppCompatActivity implements View.OnClickListener{//定义歌曲名称的数组public String[] musicName={"Innocence", "刚刚好","不用去猜"};private static SeekBar sb;//定义进度条private static TextView tv_progress, tv_total, name_song;//定义开始和总时长,歌曲名控件private ObjectAnimator animator;//定义旋转的动画private MusicService.MusicControl musicControl;//音乐控制类private Button play; //播放按钮private Button pause; //暂停按钮private Button con; //继续播放按钮private Button pre; //上一首按钮private Button next; //下一首按钮private ImageView exit; //退出按钮private ImageView iv_music; //歌手图片框Intent intent1, intent2; //定义两个意图MyServiceConn conn; //服务连接private boolean isUnbind = false;//记录服务是否被解绑public int change = 0; //记录下标的变化值@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_music);//去除标题栏ActionBar actionBar = getSupportActionBar();if(actionBar!= null){actionBar.hide();}//获得意图intent1 = getIntent();//初始化initView();}//初始化private void initView(){//依次绑定控件tv_progress = findViewById(R.id.tv_progress);tv_total = findViewById(R.id.tv_total);sb = findViewById(R.id.sb);name_song = findViewById(R.id.song_name);iv_music = findViewById(R.id.iv_music);play = findViewById(R.id.btn_play);pause = findViewById(R.id.btn_pause);con = findViewById(R.id.btn_continue_play);pre = findViewById(R.id.btn_pre);next = findViewById(R.id.btn_next);exit = findViewById(R.id.btn_exit);//依次设置监听器play.setOnClickListener(this);pause.setOnClickListener(this);con.setOnClickListener(this);pre.setOnClickListener(this);next.setOnClickListener(this);exit.setOnClickListener(this);//创建意图对象intent2 = new Intent(this, MusicService.class);conn = new MyServiceConn();//创建服务连接对象bindService(intent2, conn,BIND_AUTO_CREATE);//绑定服务//从歌曲列表传过来的歌曲名String name = intent1.getStringExtra("songname");//设置歌曲名显示name_song.setText(name);//定义歌曲列表传过来的下标positionString position = intent1.getStringExtra("position");//将字符串转化为整型iint i = parseInt(position);//图像框设置为frag1里面的图标数组,下标为iiv_music.setImageResource(SongPage.icons[i]);//为滑动条添加事件监听sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@RequiresApi(api = Build.VERSION_CODES.KITKAT)@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {//当滑动条到末端时,将message对象发送出去if (progress == sb.getMax()){}}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {//滑动条开始滑动时调用}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//滑动条停止滑动时调用//根据拖动的进度改变音乐播放进度int progress = seekBar.getProgress();//获取seekBar的进度musicControl.seekTo(progress);//改变播放进度}});animator= ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);animator.setDuration(10000);//动画旋转一周的时间为10秒animator.setInterpolator(new LinearInterpolator());//匀速animator.setRepeatCount(-1);//-1表示设置动画无限循环}//歌曲进度条的消息机制public static Handler handler = new Handler(){//创建消息处理器对象//在主线程中处理从子线程发送过来的消息@Overridepublic void handleMessage(Message msg){Bundle bundle = msg.getData();//获取从子线程发送过来的音乐播放进度int 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) {//获取歌曲名的下标字符串String index = intent1.getStringExtra("position");//将字符串转为整数int i = parseInt(index);switch (v.getId()){case R.id.btn_play://播放按钮点击事件play.setVisibility(View.INVISIBLE);musicControl.play(i);animator.start();break;//这里musicName.length-1表示的最后一首歌的下标,即歌曲总数-1case R.id.btn_pre://播放上一首if((i + change) < 1) {change = musicName.length - 1 - i;iv_music.setImageResource(SongPage.icons[i + change]);name_song.setText(musicName[i + change]);musicControl.play(i + change);pause.setVisibility(View.VISIBLE);animator.start();break;} else {change--;iv_music.setImageResource(SongPage.icons[i + change]);name_song.setText(musicName[i + change]);musicControl.play(i + change);pause.setVisibility(View.VISIBLE);animator.start();break;}case R.id.btn_next://播放下一首if((i + change) == musicName.length - 1) {change = -i;iv_music.setImageResource(SongPage.icons[i + change]);name_song.setText(musicName[i + change]);musicControl.play(i + change);pause.setVisibility(View.VISIBLE);animator.start();break;} else {change++;iv_music.setImageResource(SongPage.icons[i + change]);name_song.setText(musicName[i + change]);musicControl.play(i + change);pause.setVisibility(View.VISIBLE);animator.start();break;}case R.id.btn_pause://暂停按钮点击事件pause.setVisibility(View.INVISIBLE);con.setVisibility(View.VISIBLE);musicControl.pausePlay();animator.pause();break;case R.id.btn_continue_play://继续播放按钮点击事件con.setVisibility(View.INVISIBLE);pause.setVisibility(View.VISIBLE);musicControl.continuePlay();animator.start();break;case R.id.btn_exit://退出按钮点击事件unbind(isUnbind);isUnbind = true;finish();break;}}@Overrideprotected void onDestroy(){super.onDestroy();unbind(isUnbind);//解绑服务}
}
相关的xml文件代码:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns: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"android:background="#f9d7e7"android:orientation="vertical"tools:context=".Music.MusicActivity"><ImageViewandroid:id="@+id/btn_exit"android:layout_width="20dp"android:layout_height="20dp"android:layout_marginStart="16dp"android:layout_marginTop="24dp"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"app:srcCompat="@drawable/back" /><TextViewandroid:id="@+id/song_name"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="光年之外"android:textColor="#000"android:textSize="24sp"app:layout_constraintBottom_toBottomOf="@+id/btn_exit"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="@+id/btn_exit" /><ImageViewandroid:id="@+id/iv_music"android:layout_width="250dp"android:layout_height="250dp"android:layout_marginTop="80dp"android:src="@drawable/img_01"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/btn_exit" /><SeekBarandroid:id="@+id/sb"android:layout_width="250dp"android:layout_height="20dp"android:layout_marginTop="80dp"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toBottomOf="@+id/iv_music" /><TextViewandroid:id="@+id/tv_progress"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginEnd="5dp"android:text="00:00"app:layout_constraintBottom_toBottomOf="@+id/sb"app:layout_constraintEnd_toStartOf="@+id/sb"app:layout_constraintTop_toTopOf="@+id/sb" /><TextViewandroid:id="@+id/tv_total"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="5dp"android:text="00:00"app:layout_constraintBottom_toBottomOf="@+id/sb"app:layout_constraintStart_toEndOf="@+id/sb"app:layout_constraintTop_toTopOf="@+id/sb" /><Buttonandroid:id="@+id/btn_continue_play"android:layout_width="60dp"android:layout_height="60dp"android:background="@drawable/play"app:layout_constraintBottom_toBottomOf="@+id/btn_pre"app:layout_constraintEnd_toStartOf="@+id/btn_next"app:layout_constraintStart_toEndOf="@+id/btn_pre"app:layout_constraintTop_toTopOf="@+id/btn_pre" /><Buttonandroid:id="@+id/btn_pause"android:layout_width="60dp"android:layout_height="60dp"android:background="@drawable/pause"app:layout_constraintBottom_toBottomOf="@+id/btn_next"app:layout_constraintEnd_toStartOf="@+id/btn_next"app:layout_constraintStart_toEndOf="@+id/btn_pre"app:layout_constraintTop_toTopOf="@+id/btn_next" /><Buttonandroid:id="@+id/btn_pre"android:layout_width="40dp"android:layout_height="40dp"android:layout_marginStart="24dp"android:background="@drawable/pre"app:layout_constraintBottom_toBottomOf="@+id/btn_next"app:layout_constraintStart_toStartOf="@+id/tv_progress"app:layout_constraintTop_toTopOf="@+id/btn_next" /><Buttonandroid:id="@+id/btn_next"android:layout_width="40dp"android:layout_height="40dp"android:layout_marginTop="100dp"android:layout_marginEnd="24dp"android:background="@drawable/next"app:layout_constraintEnd_toEndOf="@+id/tv_total"app:layout_constraintTop_toBottomOf="@+id/tv_total" /><Buttonandroid:id="@+id/btn_play"android:layout_width="60dp"android:layout_height="60dp"android:background="@drawable/play"app:layout_constraintBottom_toBottomOf="@+id/btn_pre"app:layout_constraintEnd_toStartOf="@+id/btn_next"app:layout_constraintStart_toEndOf="@+id/btn_pre"app:layout_constraintTop_toTopOf="@+id/btn_pre" /></androidx.constraintlayout.widget.ConstraintLayout>
三、源码获取
✨还可以关注我的公众号《编程乐学》,菜单栏,有很多优质的资料等你来学习。