简单的音乐播放器(老师布置的小作业)

简单的音乐播放器(老师布置的小作业),第1张

简单的音乐播放器(老师布置的小作业)

请看效果 

简单的音乐播放器

开发工具:Android Studio 

涉及到的类:

涉及到的layout(有一个是多余的item_layout.xml)

悄悄说一句:有的命名不规范,勿怪。

登录界面

登录界面 activity_login.xml




    

        

        



        

    

    

        

            


            
        

        

            

            

        

        

            

            

        

        

            

登录界面 MyActivityLogin

import android.app.Activity;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NotificationCompat;

import com.example.mymusic.R;

public class MyActivityLogin extends Activity {

    private static final String TAG = "lzs";
    Button btn;
    EditText num;
    EditText pw;
    String num1;
    String password;
    Intent intent1;
    private NotificationManager notificationManager;
    private Notification notification;
    private Toolbar toolbar;
    private Button btn_login;
    private SharedPreferences sp;


    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        ActivityCollector.addActivity(this);
        num = findViewById(R.id.num);
        pw = findViewById(R.id.pw);

        sp = getSharedPreferences("mrsoft",MODE_PRIVATE);

        //注册
        //自动登录
        //手动登录

    }

    @Override
    public void onStart()
    {
        super.onStart();
    }

    @Override
    public void onResume()
    {
        super.onResume();
    }

    @Override
    public void onPause()
    {
        super.onPause();
    }

    @Override
    public void onStop()
    {
        super.onStop();
    }

    @Override
    public void onRestart()
    {
        super.onRestart();
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }



    //重写onActivityResult
    @Override
    protected void onActivityResult(int requestCode,int resultCode,Intent data){
        super.onActivityResult(requestCode,resultCode,data);
        if(requestCode == 1 && resultCode == 1){
            String returnData = data.getStringExtra("data");
            TextView tvDo = (TextView) findViewById(R.id.tvDoThing);
            tvDo.setText(returnData);

        }
    }


    //注册
    public void two5(View view)
    {
        boolean b = num.getText().toString()==null;
        boolean c= pw.getText()==null;
        Log.i(TAG, "two5: "+b);
        Log.i(TAG, "two5: "+c);
        Log.i(TAG, "two5: "+num.getText());
        Log.i(TAG, "two5: "+pw.getText());
        if(!TextUtils.isEmpty(num.getText()) && !TextUtils.isEmpty(pw.getText()))
        {
            String in_username = num.getText().toString(); //获取输入的账号
            String in_password = pw.getText().toString(); //获取输入的密码
            SharedPreferences.Editor editor = sp.edit(); //获取Editer对象
            editor.putString("username",in_username); //保存账号
            editor.putString("password",in_password); //保存密码
            editor.commit();
            Toast.makeText(MyActivityLogin.this,"注册成功",Toast.LENGTH_SHORT).show();
            //捕获数据并封装数据
            num1 = num.getText().toString();
            password = pw.getText().toString();
            intent1 = new Intent(this,MyActivityZhuce.class);
            intent1.putExtra("id",num1);
            intent1.putExtra("ps",password);
            startActivityForResult(intent1,1);
            notificationManager.notify(1,notification);
        }else {
            Toast.makeText(MyActivityLogin.this,"账号或密码填写错误",Toast.LENGTH_SHORT).show();
        }

    }

    //登录
    public void two6(View view) {

        if(!TextUtils.isEmpty(num.getText()) && !TextUtils.isEmpty(pw.getText())){
            String username = sp.getString("username","null");//获取账号
            String password = sp.getString("password","null");//获取密码
            String in_username = num.getText().toString(); //获取输入的账号
            String in_password = pw.getText().toString(); //获取输入的密码
            SharedPreferences.Editor editor = sp.edit(); //获取Editer对象
            if(in_username.equals(username) && in_password.equals(password)){
                //跳转
                Intent it1 = new Intent(MyActivityLogin.this, MainActivity1.class);
                startActivity(it1);
                Toast.makeText(MyActivityLogin.this,"登录成功",Toast.LENGTH_SHORT).show();
            }else {
                Toast.makeText(MyActivityLogin.this,"账号或密码错误",Toast.LENGTH_SHORT).show();
            }
        }else {
            Toast.makeText(MyActivityLogin.this,"账号或密码填写错误",Toast.LENGTH_SHORT).show();
        }

    }

}

注册页面

注册页面 activity_three.xml (这命名你们可以改一下,我现在才发现,就不改了)




    

        
            
        

        

            
        

    

    


        

注册页面 MyActivityZhuce

import android.app.alertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;

import com.example.mymusic.R;

public class MyActivityZhuce extends AppCompatActivity {

    TextView tv;
    private static final String TAG="lzs";

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);
        ActivityCollector.addActivity(this);
        tv=findViewById(R.id.tishi);

        Intent intent = getIntent();

        String id = intent.getStringExtra("id");
        String ps = intent.getStringExtra("ps");
        tv.setText("您好,欢迎您!"+id+"您的密码是:"+ps);
        
    }

    @Override
    public void onStart()
    {
        super.onStart();
    }

    @Override
    public void onResume()
    {
        super.onResume();
    }

    @Override
    public void onPause()
    {
        super.onPause();
    }

    @Override
    public void onStop()
    {
        super.onStop();
    }

    @Override
    public void onRestart()
    {
        super.onRestart();
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        ActivityCollector.removeActivity(this);
    }

    //隐式启动
    public void three(View view){
        Intent intent = new Intent(MyActivityZhuce.this,MyActivityLogin.class);
        startActivity(intent);

    }

}

音乐播放列表页面

首先解释一下,这个页面的布局情况,它是activity里放了fragment的,实现歌曲和专辑两选项的切换,如下图(左边的是activity,右边是fragment)

 

 左边activity_main_music2.xml




    

        

    

    

        

        
    

    

        

    

    

    
    

 右边music_list.xml




    

        

            

            

            

            

        

        

        
    


 专辑页面 frag2_layout.xml(我就放了一个ListView,并且没有设置样式和内容,有兴趣的可以自己加一些专辑图片什么的)




   

 每首音乐的 item样式item_local_music.xml(可以根据兴趣设置自己的样式)



    
        
        

        

        

        
        
    

 到此我把音乐播放列表的布局都讲完了,接下来是它们的逻辑。

MainActivity1 类
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.widget.frameLayout;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager;
import androidx.fragment.app.FragmentTransaction;

import com.example.mymusic.R;
import com.synnapps.carouselview.CarouselView;
import com.synnapps.carouselview.ImageClickListener;
import com.synnapps.carouselview.ImageListener;

public class MainActivity1 extends AppCompatActivity implements View.onClickListener {
    private frameLayout content;
    private TextView tv1,tv2;
    private FragmentManager fm;
    private FragmentTransaction ft;

    CarouselView carouselView;

    private int[] images = new int[]{
            R.drawable.img11,
            R.drawable.img22,
            R.drawable.img33,
            R.drawable.img44,
            R.drawable.img55
    };
    private com.example.mymusic.mymusic.frag1 mFragmentConversation;
    private frag2 mFragmentConversation2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_music2);
        ActivityCollector.addActivity(this);
        carouselView = findViewById(R.id.carouselView);
        //设置轮播图的页面数量
        carouselView.setPageCount(images.length);
        carouselView.setImageListener(imageListener);
        carouselView.setImageClickListener(new ImageClickListener() {
            @Override
            public void onClick(int position) {
            }
        });

        content=(frameLayout)findViewById(R.id.content);

        tv1=(TextView)findViewById(R.id.menu1);
        tv2=(TextView)findViewById(R.id.menu2);

        tv1.setonClickListener(this);
        tv2.setonClickListener(this);

        fm=getSupportFragmentManager();//若是继承FragmentActivity,fm=getFragmentManger();
        ft=fm.beginTransaction();
        ft.replace(R.id.content,new com.example.mymusic.mymusic.frag1());//默认情况下Fragment1
        ft.commit();
        InitFragment();
        getSupportFragmentManager().beginTransaction()
                         .add(R.id.content, mFragmentConversation).commit();
    }

    private void InitFragment() {
                 mFragmentConversation = new com.example.mymusic.mymusic.frag1();
                 mFragmentConversation2 = new frag2();
             }

    ImageListener imageListener = new ImageListener() {
        @Override
        public void setImageForPosition(int position, ImageView imageView) {

            imageView.setImageResource(images[position]);
        }
    };

    @Override
    public void onClick(View v){
        ft=fm.beginTransaction();
        FragmentTransaction mTransaction = getSupportFragmentManager()
                         .beginTransaction();
        switch (v.getId()){
            case R.id.menu1:
                if (!getSupportFragmentManager().getFragments().contains(mFragmentConversation)) {
                    mTransaction.add(R.id.content, mFragmentConversation);
                }
                mTransaction.show(mFragmentConversation);
                HideOtherFragments(mFragmentConversation);
                break;
            case R.id.menu2:
                if (!getSupportFragmentManager().getFragments().contains(mFragmentConversation2)) {
                    mTransaction.add(R.id.content, mFragmentConversation2);
                }
                mTransaction.show(mFragmentConversation2);
                HideOtherFragments(mFragmentConversation2);
                break;
            default:
                break;
        }

        mTransaction.commit();

    }
    
      private void HideOtherFragments(Fragment fragment) {
                 if (getSupportFragmentManager().getFragments() == null) {
                         return;
                     }
                for (Fragment fm : getSupportFragmentManager().getFragments()) {
                         if (fm != fragment) {
                                 getSupportFragmentManager().beginTransaction().hide(fm)
                                     .commit();
                               }
                    }
         }
    @Override
    protected void onDestroy() {
        super.onDestroy();

    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode == KeyEvent.KEYCODE_BACK){
            moveTaskToBack(true);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

}

数据源类    localMusicBean

package com.example.mymusic.mymusic;

import java.io.Serializable;

public class localMusicBean implements Serializable {
    private String id; //歌曲id
    private String song; //歌曲名称
    private String singer; //歌手名称
    private String album; //专辑名称
    private String duration; //歌曲时长
    private String path; //歌曲路径
    private String albumArt;  //专辑地址

    public localMusicBean() {
    }

    public localMusicBean(String id, String song, String singer, String album, String duration, String path, String albumArt) {
        this.id = id;
        this.song = song;
        this.singer = singer;
        this.album = album;
        this.duration = duration;
        this.path = path;
        this.albumArt = albumArt;
    }

    public String getAlbumArt() {
        return albumArt;
    }

    public void setAlbumArt(String albumArt) {
        this.albumArt = albumArt;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getSong() {
        return song;
    }

    public void setSong(String song) {
        this.song = song;
    }

    public String getSinger() {
        return singer;
    }

    public void setSinger(String singer) {
        this.singer = singer;
    }

    public String getAlbum() {
        return album;
    }

    public void setAlbum(String album) {
        this.album = album;
    }

    public String getDuration() {
        return duration;
    }

    public void setDuration(String duration) {
        this.duration = duration;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }
}

适配器类  LocalMusicAdapter2

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;


import com.example.mymusic.R;

import java.util.List;

public class LocalMusicAdapter2 extends RecyclerView.Adapter{
    Context context;
    List mDatas;

    onItemClickListener onItemClickListener;

    //接口回调
    public void setonItemClickListener(onItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }

    public interface OnItemClickListener{
        public void onItemClick(View view,int position);
    }

    public LocalMusicAdapter2(Context context, List mDatas) {
        this.context = context;
        this.mDatas = mDatas;
    }

    @NonNull
    @Override
    public LocalMusicViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_local_music,parent,false);
        LocalMusicViewHolder holder = new LocalMusicViewHolder(view);
        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull LocalMusicViewHolder holder, @SuppressLint("RecyclerView") final int position) {

        localMusicBean musicBean = mDatas.get(position);
        holder.idTv.setText(musicBean.getId());
        holder.songTv.setText(musicBean.getSong());
        holder.singerTv.setText(musicBean.getSinger());
        holder.albumTv.setText(musicBean.getAlbum());
        holder.timeTv.setText(musicBean.getDuration());

        holder.itemView.setonClickListener(new View.onClickListener() {
            @Override
            public void onClick(View v) {
                onItemClickListener.onItemClick(v,position);
            }
        });
    }

    @Override
    public int getItemCount() {
        return mDatas.size();
    }


    class LocalMusicViewHolder extends RecyclerView.ViewHolder{
        TextView idTv,songTv,singerTv,albumTv,timeTv;
        public LocalMusicViewHolder(View itemView) {
            super(itemView);
            idTv = itemView.findViewById(R.id.item_local_music_num);
            songTv = itemView.findViewById(R.id.item_local_music_song);
            singerTv = itemView.findViewById(R.id.item_local_music_singer);
            albumTv = itemView.findViewById(R.id.item_local_music_album);
            timeTv = itemView.findViewById(R.id.item_local_music_durtion);
        }
    }
}
活动管理类 ActivityCollector(便于管理活动是否销毁)
import android.app.Activity;

import java.util.linkedList;

public class ActivityCollector {
    public static linkedList activities = new linkedList();
    public static void addActivity(Activity activity)
    {
        activities.add(activity);
    }

    public static void removeActivity(Activity activity)
    {
        activities.remove(activity);
    }

    public static void finishAll()
    {
        for (Activity activity:activities ) {
            if(!activity.isFinishing())
            {
                activity.finish();
            }
        }
    }
}

音乐播放列表类  frag1(继承自Fragment)

import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;


import com.example.mymusic.R;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class frag1 extends Fragment implements View.OnClickListener{
    private static final String TAG = "lzs";
    private View view;
    public String name;
    public static int icons=R.drawable.iuyuantu;
    private ImageView btn_music;
    RecyclerView musicRv;
    //    数据源
    private List mDatas;
    private LocalMusicAdapter2 adapter;
    private MediaPlayer mediaPlayer;
    private Intent it;
    public String addr=null;
    public int position1=-1;
    private int idd;
    private TextView t1,t2;


    @Override
    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){

        // 可能初始化一个新实例的默认值的成员
        view=inflater.inflate(R.layout.music_list,container,false);
        musicRv = view.findViewById(R.id.local_music_rv1);
        mediaPlayer = new MediaPlayer();
        mDatas = new ArrayList<>();
        t1=view.findViewById(R.id.local_music_bottom_tv_song);
        t2=view.findViewById(R.id.local_music_bottom_tv_singer);
        btn_music=view.findViewById(R.id.local_music_icon);
        btn_music.setonClickListener(this);
        //创建适配器对象
        adapter = new LocalMusicAdapter2(frag1.this.getContext(), mDatas);
        musicRv.setAdapter(adapter);
        //设置布局管理器
        LinearLayoutManager layoutManager = new LinearLayoutManager(frag1.this.getContext(), LinearLayoutManager.VERTICAL, false);
        musicRv.setLayoutManager(layoutManager);
        //加载本地数据源
        loadLocalMusicData();
        //设置每一项的点击事件
        setEventListener();
        Log.i(TAG, "onCreateView: "+position1);
        return view;
    }

    private void loadLocalMusicData() {
        
        //1.获取ContentResolver对象
        ContentResolver resolver = frag1.this.getContext().getContentResolver();
        //2.获取本地音乐存储的Uri地址
        Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        Log.i(TAG, "loadLocalMusicdata: "+uri);
        //3 开始查询地址
        Cursor cursor = resolver.query(uri, null, null, null, null);
        Log.i(TAG, "loadLocalMusicdata: "+cursor);
        //4.遍历Cursor
        int id = 0;
        while (cursor.moveTonext()) {
            String song = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
            String singer = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
            String album = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
            id++;
            String sid = String.valueOf(id);
            String path = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.DATA));
            long duration = cursor.getLong(cursor.getColumnIndex(MediaStore.Audio.Media.DURATION));
            SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
            String time = sdf.format(new Date(duration));
            //获取专辑图片主要是通过album_id进行查询
            String album_id = cursor.getString(cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
            //将一行当中的数据封装到对象当中
            localMusicBean bean = new localMusicBean(sid, song, singer, album, time, path,"");
            mDatas.add(bean);
        }
        idd=id;
        Log.i(TAG, "loadLocalMusicdata: "+mDatas);
        //数据源变化,提示适配器更新
        adapter.notifyDataSetChanged();
    }

    private void setEventListener() {
        
        adapter.setonItemClickListener(new LocalMusicAdapter2.onItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                position1 = position;
                Log.i(TAG, "OnItemClick: "+position1);
                addr=mDatas.get(position).getPath();
                t1.setText(mDatas.get(position).getSong());
                t2.setText(mDatas.get(position).getSinger());
                it = new Intent(frag1.this.getContext(), com.example.mymusic.mymusic.Music_Activity.class);
                it.putExtra("position",String.valueOf(1));
                it.putExtra("id1",position); //点击歌曲id
                it.putExtra("id2",idd); //歌曲总数
                it.putExtra("data1", (Serializable) mDatas); //歌曲集合
                it.putExtra("musicI",0); //传0表示用户点击的是歌曲列表里的歌曲,而不是返回播放界面
                startActivity(it);

            }
        });
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.local_music_icon:

                it = new Intent(frag1.this.getContext(), com.example.mymusic.mymusic.Music_Activity.class);
                it.putExtra("data1", (Serializable) mDatas);
                it.putExtra("musicI",1); //传1表示用户点击的是那个音箱图标,只是想返回播放界面,而不是要换歌
                it.putExtra("id2",idd); //歌曲总数
                it.putExtra("id1",position1); //传歌曲id
                startActivity(it);
                break;

        }

    }

    @Override
    public void onDestroy() {
        super.onDestroy();

    }
}

专辑 类frag2(继承自Fragment)

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.fragment.app.Fragment;

import com.example.mymusic.R;

public class frag2 extends Fragment {
    private View zj;

    public View onCreateView(final LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        zj = inflater.inflate(R.layout.frag2_layout, null);
        return zj;

    }
}

到此音乐播放列表的布局文件和类都写完了,接下来是

音乐播放界面

音乐播放界面 activity_music




    
    
    
    
        
        

    
    
    

        

            
            
            

            
        

        

            

            

            

            

            
        
    

    

    

        

        
    

    

        

        

        

        

        

    


音乐播放界面类 Music_Activity

import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
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 android.widget.Toast;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;


import com.example.mymusic.R;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

public class Music_Activity extends AppCompatActivity implements View.OnClickListener{
    private static final String TAG = "lzs";
    private static SeekBar sb;
    private static TextView tv_progress,tv_total,song_name;
    private ObjectAnimator animator;
    private String name;
    private Intent intent1;
    //    数据源
    private List mDatas1;
    private ImageView play1,last1,next1;
    private int num;
    private int id;
    private ImageView btn_xunhuang;
    private boolean aa=true;
    private boolean bb=true;
    private ImageView btn_shouc;
    private int musicI;
    private ImageView iv_music;
    private MediaPlayer player;
    private Timer timer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music);
        ActivityCollector.addActivity(this);
        //intent 通信
        intent1=getIntent();
        mDatas1=(List) getIntent().getSerializableExtra("data1");//接收歌曲集合
        num = intent1.getIntExtra("id2",0);//歌曲总数
        id = intent1.getIntExtra("id1",0);//点击歌曲id
        player=new MediaPlayer();//创建音乐播放器对象
        init(); //初始化布局控件
        Log.i(TAG, "onCreate: ");
    }
    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);
        song_name=findViewById(R.id.song_name);
        play1=findViewById(R.id.btn_play);
        last1=findViewById(R.id.btn_last);
        next1=findViewById(R.id.btn_next);
        btn_xunhuang=findViewById(R.id.btn_xuhuang);
        btn_shouc=findViewById(R.id.btn_shouc);

        play1.setonClickListener(this);
        last1.setonClickListener(this);
        next1.setonClickListener(this);
        btn_xunhuang.setonClickListener(this);
        btn_shouc.setonClickListener(this);

        if(id!=-1)
        {
            name=mDatas1.get(id).getSong();
            song_name.setText(name);
        }

        //为滑动条添加事件监听
        sb.setonSeekBarChangeListener(new SeekBar.onSeekBarChangeListener() {
            @RequiresApi(api = Build.VERSION_CODES.KITKAT)
            @Override
            public 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的进度
                seekTo(progress);//改变播放进度
            }
        });
        iv_music=(ImageView)findViewById(R.id.iv_music);
        iv_music.setImageResource(frag1.icons); //设置专辑图片

        animator=ObjectAnimator.ofFloat(iv_music,"rotation",0f,360.0f);
        animator.setDuration(10000);//动画旋转一周的时间为10秒
        animator.setInterpolator(new LinearInterpolator());//匀速
        animator.setRepeatCount(-1);//-1表示设置动画无限循环
        if(id!=-1)
        animator.start();

    }

    @Override
    public void onClick(View view) {

        switch (view.getId()){
            case R.id.btn_play://播放按钮点击事件
                if(id==-1)
                {
                    id=0;
                    play1.setImageResource(R.drawable.play1);
                    song_name.setText(mDatas1.get(id).getSong());
                    play(mDatas1.get(id).getPath());
                    animator.start();
                }else {
                    if(isPlay())
                    {
                        play1.setImageResource(R.drawable.pause1);
                        pausePlay();
                        animator.pause();
                    }else
                    {

                        play1.setImageResource(R.drawable.play1);
                        continuePlay();
                        if(animator.isPaused())
                            animator.resume();
                        else
                        {
                            animator.start();
                        }

                    }
                }
                break;
            case R.id.btn_last://上一首


                if(id<=0)
                {
                    Toast.makeText(this,"已经是第一首了,没有上一曲!",Toast.LENGTH_SHORT).show();
                }else
                {
                    if(isPlay())
                    {
                        animator.pause();
                        animator.clone();
                        id--;
                        song_name.setText(mDatas1.get(id).getSong());
                        play(mDatas1.get(id).getPath());
                        animator.start();
                    }else
                    {
                        animator.pause();
                        animator.clone();
                        play1.setImageResource(R.drawable.play1);
                        id--;
                        song_name.setText(mDatas1.get(id).getSong());
                        play(mDatas1.get(id).getPath());
                        animator.start();
                    }

                }
                break;
            case R.id.btn_next://下一首
                if(id>=num)
                {
                    Toast.makeText(this,"已经是最后一首了,没有下一曲!",Toast.LENGTH_SHORT).show();
                }else
                {
                    if(isPlay())
                    {
                        animator.pause();
                        animator.clone();
                        id++;
                        song_name.setText(mDatas1.get(id).getSong());
                        play(mDatas1.get(id).getPath());
                        animator.start();
                    }
                    else
                    {
                        animator.pause();
                        animator.clone();
                        id++;
                        song_name.setText(mDatas1.get(id).getSong());
                        play1.setImageResource(R.drawable.play1);
                        play(mDatas1.get(id).getPath());
                        animator.start();

                    }
                }
                break;
            case R.id.btn_xuhuang:
                 btn_xunhuang.setSelected(aa);
                if(aa==true)
                {
                    Toast.makeText(Music_Activity.this,"顺序播放",Toast.LENGTH_SHORT).show();
                    aa=false;
                }
                else
                {
                    Toast.makeText(Music_Activity.this,"单曲循环",Toast.LENGTH_SHORT).show();
                    aa=true;
                }
                 break;
            case R.id.btn_shouc:
                btn_shouc.setSelected(bb);
                if(bb==true)
                {
                    Toast.makeText(Music_Activity.this,"收藏成功",Toast.LENGTH_SHORT).show();
                    bb=false;
                }
                else
                {
                    Toast.makeText(Music_Activity.this,"取消收藏",Toast.LENGTH_SHORT).show();
                    bb=true;
                }
                break;
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");

    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.i(TAG, "onPause: ");
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.i(TAG, "onResume: ");
    }

    @Override
    protected void onStart() {
        Log.i(TAG, "onStart: ");
        super.onStart();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus)
    {
        Log.i(TAG, "onWindowFocusChanged: ");
        if (hasFocus)
        {
            Log.i("lsh123", "onWindowFocusChanged: "+isPlay());
            if(id!=-1)
            {
                song_name.setText(mDatas1.get(id).getSong());
                musicI=intent1.getIntExtra("musicI",-1);
                Log.i(TAG, "onWindowFocusChanged: "+musicI);
                if(musicI==0)
                {
                    play1.setImageResource(R.drawable.play1);
                    play(mDatas1.get(id).getPath());
                    animator.start();

                }
            }

        }
    }

    //在Musiv_Activity从后台重新切换到前台时,更新当前intent对象,已达到更新数据的目的
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
         intent1 = getIntent();
        id = intent1.getIntExtra("id1",-1);
        Log.i(TAG, "onNewIntent: "+id);
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        Log.i("lsh123", "onDestroy1: ");
    }
    //让activity进入后台,不销毁
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        Log.i(TAG, "onKeyDown: ");
        if(keyCode == KeyEvent.KEYCODE_BACK){
            Intent it = new Intent(Music_Activity.this,MainActivity1.class);
            startActivity(it);
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
    public void addTimer(){ //添加计时器用于设置音乐播放器中的播放进度条
        if(timer==null){
            timer=new Timer();//创建计时器对象
            TimerTask task=new TimerTask() {
                @Override
                public void run() {
                    if (player==null) return;
                    int duration=player.getDuration();//获取歌曲总时长
                    int currentPosition=player.getCurrentPosition();//获取播放进度
                    Message msg=Music_Activity.handler.obtainMessage();//创建消息对象
                    //将音乐的总时长和播放进度封装至消息对象中
                    Bundle bundle=new Bundle();
                    bundle.putInt("duration",duration);
                    bundle.putInt("currentPosition",currentPosition);
                    msg.setData(bundle);
                    //将消息发送到主线程的消息队列
                    Music_Activity.handler.sendMessage(msg);
                    Log.i("lsh123", "run: ");
                }
            };
            //开始计时任务后的5毫秒,第一次执行task任务,以后每500毫秒执行一次
            timer.schedule(task,5,500);
        }
    }

    //播放歌曲
        public void play(String str){//String path
            Log.i("lsh123", "play: "+str);
            Uri uri=Uri.parse(str+"");
            try{
                player.reset();//重置音乐播放器
                //加载多媒体文件
                Log.i("lsh123", "play: 123"+str);
                player=MediaPlayer.create(getApplicationContext(),uri);
                Log.i("lsh123", "play: "+str);
                player.start();//播放音乐
                addTimer();//添加计时器
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        public boolean isPlay(){
            if(player.isPlaying())
                return true;
            else return false;
        }
        public void pausePlay(){
            player.pause();//暂停播放音乐
        }
        public void continuePlay(){
            player.start();//继续播放音乐
        }
        public void seekTo(int progress){
            player.seekTo(progress);//设置音乐的播放位置
        }


    public static Handler handler=new Handler(){//创建消息处理器对象
        //在主线程中处理从子线程发送过来的消息
        @SuppressLint("HandlerLeak")
        @Override
        public 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){//如果歌曲的时间中的分钟小于10
                strMinute="0"+minute;//在分钟的前面加一个0
            }else{
                strMinute=minute+"";
            }
            if (second<10){//如果歌曲中的秒钟小于10
                strSecond="0"+second;//在秒钟前面加一个0
            }else{
                strSecond=second+"";
            }
            tv_total.setText(strMinute+":"+strSecond);
            //歌曲当前播放时长
            minute=currentPosition/1000/60;
            second=currentPosition/1000%60;
            if(minute<10){//如果歌曲的时间中的分钟小于10
                strMinute="0"+minute;//在分钟的前面加一个0
            }else{
                strMinute=minute+" ";
            }
            if (second<10){//如果歌曲中的秒钟小于10
                strSecond="0"+second;//在秒钟前面加一个0
            }else{
                strSecond=second+" ";
            }
            tv_progress.setText(strMinute+":"+strSecond);
        }
    };

}

还有一些配置信息

AndroidManifest.xml




    
    
    
    
    
    


    
        
            
                

                
            
        
        
        
        
    

模块内的build.gradle

plugins {
    id 'com.android.application'
}

android {
    compileSdk 30

    defaultConfig {
        applicationId "com.example.mymusic"
        minSdk 21
        targetSdk 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
//添加包路径

    //开启dataBinding功能支持
    dataBinding {
        enabled = true
    }
    // 自定义打包名称
    android.applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "ac.apk"
        }
    }


    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {

    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    implementation 'androidx.preference:preference:1.1.1'
    testImplementation 'junit:junit:4.+'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
    //添加 RecyclerView 依赖包
    implementation "androidx.recyclerview:recyclerview:1.2.1"
    //添加 ViewPager2 依赖包
    implementation 'androidx.viewpager2:viewpager2:1.0.0'

    implementation'com.synnapps:carouselview:0.1.5'

    implementation 'org.greenrobot:eventbus:3.1.1'
}

到此,所有布局文件,类和配置信息都写完了,当然里面的逻辑思路就不具体介绍了,不然就我这

打字速度得写到什么时候,所以我就大概讲讲用到了哪些方法:

1.首先是登录界面,我是用了Shared Preferences 存储(对于注册少量用户来说,建议使用

sqlite)

2.还有就是,音乐列表和专辑两个页面的切换,其实就是activity里两个fragment的切换,注意

通过add方法添加fragment,再通过hide,show决定显示哪一个fragment,此方式是将fragment隐藏

而非重建,replace:每次都是重新创建fragment,所以为了保存数据,我采用的是add。

3.音乐列表上方的轮播图是我用第三方插件写的,当然你也可以自己写,用Handler消息机制。

4.在音乐列表和音乐播放界面跳转过程中,我让音乐播放界面直接切入后台,不销毁,从而达到数

据的保存,当然你也可以使用Service,进程间的通信解决数据交互问题。

5.音乐播放界面的音乐进度条是通过Handler消息机制实现的,每个几毫秒就向主线程发送消息,

然后修改当前进度条的值,从而达到动态的效果

6.还有很多小知识,我就不一一讲了,相信你们也能看的懂,没有用到特别难的知识,功能也挺简

单的。

GitHub链接:https://github.com/1577643176/Simplemusicplayer.git

联系QQ:1577643176

以上是我个人总结,难免会有不妥之处,欢迎指正,谢谢。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4667620.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存