Android 音乐播放器

这篇具有很好参考价值的文章主要介绍了Android 音乐播放器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

小项目开发——Android 音乐播放器

一、题目

音乐播放器.

要求Activity编程、ListView编程、SeekBar编程、ExoPlayer编程(播放暂停停止上一首下一首),音乐文件放在assets/music目录下,界面自拟.

◼ 期望最终效果:

android 音乐首页,小项目开发,java,android studio


二、实际最终效果

◼ 分别对应activity_music_list.xmlactivity_my_music_player.xml的视图.

◼ 点击列表任何一个元素都可以直接跳转到音乐播放界面.

android 音乐首页,小项目开发,java,android studio


三、模块分析

android 音乐首页,小项目开发,java,android studio

◼ 从题目所期望的效果来看,需要实现的主要分为3大模块:音乐列表进度条功能按钮.

◼ 还有2大可自定义模块:状态栏导航栏.

但为了尽可能实现像市面上的大部分音乐播放器的界面,我在不改变题目原有主功能的基础上进行了重新设计,即设计了2个 Activity(MusicListActivity.javaMyMusicPlayerActivity.java)及其对应 Layout(activity_music_list.xmlactivity_my_music_player.xml),分别控制 音乐列表音乐播放,而不是将它们写在一起.


四、思维导图

◼ 基于以上分析我决定分以下4大模块来进行编程:状态栏导航栏音乐列表音乐播放.

◼ 并以 LayoutActivity 两大块 进行阐述.

android 音乐首页,小项目开发,java,android studio


五、Layout

1. 自定义 Theme

Path:res/values/themes.xml,添加自定义主题样式,

<style name="Theme.MyMusic" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
    <!-- Primary brand color. -->
    <item name="colorPrimary">#B22196F3</item>
    <item name="colorPrimaryVariant">#8B19ADD2</item>
    <item name="colorOnPrimary">#FFFFFF</item>
    <!-- Status bar color. -->
    <item name="android:statusBarColor">#B91976D2</item>
</style>

◼ 并应用在了音乐列表和音乐播放的 Activity 中(即状态栏、导航栏)——AndroidManifest.xml.

android:theme="@style/Theme.MyMusic"

2. 导航栏 LOGO

music_list.xml:将 LOGO 资源图片(icon_music_list.png)修改为 白色 以适配导航栏的背景色.

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <bitmap android:src="@drawable/icon_music_list" android:tint="@color/white" />
    </item>
</layer-list>

注:LOGO 图标 见 ———> [Music Player/icon_music_list.png · Re.Gin/CSDN - 码云 - 开源中国 (gitee.com)](https://gitee.com/ReGinWZY/csdn/blob/master/Music Player/icon_music_list.png)

3. 音乐列表布局

◼ 文件名:activity_music_list.xml

◼ 采用 约束布局ConstrainLayout

◼ 布局idcl_music_list

◼ 只有一个 空白的 占满整个屏幕的ListView组件:

android 音乐首页,小项目开发,java,android studio

4. 音乐播放布局

◼ 文件名:activity_my_music_player.xml

◼ 采用 约束布局ConstrainLayout

◼ 布局idcl_music_player

注:剩下没贴图的ImageButton同右下角的ibtn_play,只是图标、位置、放缩倍率不同.

音乐封面可去网易云官网复制.

按钮图标 见 ———> [Music Player/播放按钮图标 · Re.Gin/CSDN - 码云 - 开源中国 (gitee.com)](https://gitee.com/ReGinWZY/csdn/tree/master/Music Player/播放按钮图标)

android 音乐首页,小项目开发,java,android studio

5. 设置APP图标及名字

android 音乐首页,小项目开发,java,android studio

android:icon="@drawable/headphone"
android:label="MyMusicPlayer"

注:APP 图标见 ———> [Music Player/headphone.png · Re.Gin/CSDN - 码云 - 开源中国 (gitee.com)](https://gitee.com/ReGinWZY/csdn/blob/master/Music Player/headphone.png)


六、Activity

1. 音乐列表 Activity

◼ 文件名:MusicListActivity.java

⑴ 列表元素点击监听器
AdapterView.OnItemClickListener mListenerLv = (parent, view, position, id) -> {
    mIntent.putExtra("selectedIndex", position); // 传选中音乐下标
    startActivity(mIntent); // 跳转至 MyMusicPlayerActivity
}; // end mLvListener
⑵ 获取音乐名
public void getMusics() {
    try {
        String[] musicFileNames = getAssets().list("musics");
        for (int i = 0; i < musicFileNames.length; ++i) {
            musicFileNames[i] = musicFileNames[i].split("\\.")[0]; // 以“.”分割字符串得到不含后缀的音乐名
            mMusicList.add(musicFileNames[i]);
        } // end for
        mIntent.putExtra("musicArray", musicFileNames); // 将整个音乐列表传给 MyMusicPlayerActivity
    } catch (IOException e) {
        throw new RuntimeException(e);
    } // end catch
} // end getMusics

2. 音乐播放 Activity

◼ 文件名:MyMusicPlayerActivity.java

⑴ 获取音乐列表信息
public void getIntentMsg() {
    sMusicIndex = mIntent.getIntExtra("selectedIndex", 0); // 默认第一首音乐
    sMusicArray = mIntent.getStringArrayExtra("musicArray");
} // end getIntentMsg
⑵ 音乐封面圆形剪裁和旋转动画
API 说明
circularCutting Bitmap对象进行圆形剪裁
addAnimation ImageView对象添加动画
public Bitmap circularCutting(Bitmap bitmap) {
    mBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(mBitmap);
    Paint paint = new Paint();
    paint.setShader(new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
    canvas.drawCircle(bitmap.getWidth() / 2f, bitmap.getHeight() / 2f, bitmap.getWidth() / 2f, paint);
    return mBitmap;
} // end circularCutting

◼ 首先,使用Bitmap.createBitmap()ARGB_8888一种32位颜色深度的色彩模式创建一个与原始bitmap大小相同且高质量的位图对象mBitmap.

◼ 然后,先使用Canvas对象将该位图对象绘制成一个圆形,再使用Paint对象的setShader()方法设置圆形填充色,通过BitmapShader对象将原始 bitmap作为填充纹理.

◼ 最后,将处理后的位图对象返回.

public void addAnimation(ImageView iv) {
    mAnimator = ObjectAnimator.ofFloat(iv, "rotation", 0f, 360f); // 360°旋转
    mAnimator.setDuration(40000); // 毫秒
    mAnimator.setRepeatCount(ObjectAnimator.INFINITE); // 动画无限循环
    mAnimator.setInterpolator(new LinearInterpolator()); // 线性插值器
    mAnimator.start(); // 启动动画
} // end addAnimation

◼ 首先使用ObjectAnimator.ofFloat()方法创建一个ObjectAnimator对象,将其绑定到ImageView对象的rotation属性上,设置动画的起始值和结束值,以及动画的持续时间和重复次数.

◼ 然后,使用setInterpolator()方法设置动画插值器为线性插值器.

◼ 最后调用start()方法启动动画.

⑶ 设置音乐播放相关资源
API 说明
mPlayerListener 音乐播放器监听器
initExoPlayer 初始化音乐播放器(ExoPlayer对象)
updateMusicPlayer 更新音乐播放器
updateMusicLayout 更新音乐播放器页面
Player.Listener mPlayerListener = new Player.Listener() {
    @Override
    public void onPlaybackStateChanged(int playbackState) {
        if (playbackState == ExoPlayer.STATE_READY) { // 播放器准备好了
            mExoPlayer.play();
            mPlayStateIbtn.setImageResource(R.drawable.pause);
            mTimer.schedule(new ProgressUpdate(), 0, 500);
        } // end if
    } // end onPlaybackStateChanged
}; // end mPlayerListener

public void initExoPlayer() {
    mExoPlayer = new ExoPlayer.Builder(MyMusicPlayerActivity.this).build();
    /* 一次性将所有音乐资源添加到音乐播放器中 */
    for (String musicName : sMusicArray) {
        mediaItem = MediaItem.fromUri("asset:///musics/" + musicName + ".mp3");
        mExoPlayer.addMediaItem(mediaItem);
    } // end for
    updateMusicPlayer(sMusicIndex);
    mExoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ALL); // 默认列表循环
    mPlayMode = mExoPlayer.getRepeatMode();
    mExoPlayer.addListener(mPlayerListener);
} // end initExoPlayer

◼ 对于 asset 文件夹里的资源,可以以asset:///path形式得到资源的URI.

◼ 这里一次性将 MusicListActivity 传来的所有音乐资源添加到音乐播放器中,以便后续直接通过 索引位置 进行相关操作.文章来源地址https://www.toymoban.com/news/detail-767903.html

public void updateMusicPlayer(int index) {
    updateMusicLayout(index); // 更新页面
    mExoPlayer.seekTo(index, 0);
    mExoPlayer.prepare();
} // end updateExoPlayer

public void updateMusicLayout(int index) {
    mMusicTitleTv.setText(sMusicArray[index]);
    try {
        InputStream inputStream = getAssets().open("music_images/" + sMusicArray[index] + ".jpg");
        mBitmap = BitmapFactory.decodeStream(inputStream);
        mMusicCoverIv.setImageBitmap(circularCutting(mBitmap));
        inputStream.close();
    } catch (IOException e) {
        throw new RuntimeException(e);
    } // end catch
} // end updateMusicLayout
⑷ 进度条
SeekBar.OnSeekBarChangeListener mListenerSb = new SeekBar.OnSeekBarChangeListener() {
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        /* 从用户拖动到的位置开始播放 */
        if (fromUser) {
            mExoPlayer.seekTo(sMusicIndex, progress);
        }
        /* 列表循环状态下,音乐会自动到下一首,此时需要重新渲染页面元素 */
        if (sMusicIndex != mExoPlayer.getCurrentMediaItemIndex()
            && mPlayMode == mExoPlayer.REPEAT_MODE_ALL) {
            sMusicIndex = mExoPlayer.getCurrentMediaItemIndex();
            updateMusicLayout(sMusicIndex);
            mAnimator.cancel();
            mAnimator.start();
        } // end if
    } // end onProgressChanged

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    } // end onStartTrackingTouch

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        mAnimator.resume(); // 用户停止拖动进度条,图片重新旋转
        mStartTimeTv.setText(formatPosition(seekBar.getProgress()));
    } // end onStopTrackingTouch
}; // end mListenerSb

/**
 * 内部类——定时任务类:定时更新 SeekBar 进度条
 */
private class ProgressUpdate extends TimerTask {
    @Override
    public void run() {
        runOnUiThread(() -> {
            mStartPos = mExoPlayer.getContentPosition();
            mMusicProgressSb.setProgress((int) mStartPos);
            mStartTimeTv.setText(formatPosition(mStartPos));
            mDurationPos = mExoPlayer.getDuration();
            mMusicProgressSb.setMax((int) mDurationPos);
            mDurationTimeTv.setText(formatPosition(mDurationPos));
        }); // end runOnUiThread
    } // end run
} // end ProgressUpdate

/**
 * 格式化音乐进度条起始、终止位置,显示“分:秒”
 *
 * @param pos 音乐进度条位置
 * @return “分:秒”
 */
public String formatPosition(long pos) {
    @SuppressLint("SimpleDateFormat")
    SimpleDateFormat sdf = new SimpleDateFormat("mm:ss"); // "分:秒"格式
    return sdf.format(pos);
} // end format
⑸ 功能按钮
API 说明
changePlayerMode 更换音乐播放模式
previousMusic 上一首
changePlayerState 播放/暂停
nextMusic 下一首
stopMusic 停止音乐
public void changePlayerMode() {
    if (mPlayMode == mExoPlayer.REPEAT_MODE_ALL) {
        mPlayModeIbtn.setImageResource(R.drawable.repeat_once);
        mExoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ONE);
        mPlayMode = ExoPlayer.REPEAT_MODE_ONE;
        Toast.makeText(MyMusicPlayerActivity.this, "单曲循环", Toast.LENGTH_SHORT).show();
    } else {
        mPlayModeIbtn.setImageResource(R.drawable.repeat_all);
        mExoPlayer.setRepeatMode(ExoPlayer.REPEAT_MODE_ALL);
        mPlayMode = ExoPlayer.REPEAT_MODE_ALL;
        Toast.makeText(MyMusicPlayerActivity.this, "列表循环", Toast.LENGTH_SHORT).show();
    } // end else
} // end changePlayerMode

public void previousMusic() {
    if (sMusicIndex == 0) {
        sMusicIndex = sMusicArray.length - 1;
    } else sMusicIndex--;
    mAnimator.cancel(); // 上一首取消动画
    mAnimator.start(); // 并重新开始旋转
    updateMusicPlayer(sMusicIndex);
} // end previousMusic

public void changePlayerState() {
    if (mExoPlayer.isPlaying()) {
        mExoPlayer.pause();
        mAnimator.pause(); // 暂停动画,直到遇上 resume()
        mPlayStateIbtn.setImageResource(R.drawable.play);
        mTimer.cancel();
        mTimer = new Timer();
        Toast.makeText(MyMusicPlayerActivity.this, "暂停", Toast.LENGTH_SHORT).show();
    } else {
        mExoPlayer.play();
        mAnimator.resume(); // 将暂停的动画重新从当前位置开始旋转,而不是重新开始
        mPlayStateIbtn.setImageResource(R.drawable.pause);
        mTimer = new Timer();
        mTimer.schedule(new ProgressUpdate(), 0, 500);
        Toast.makeText(MyMusicPlayerActivity.this, "播放", Toast.LENGTH_SHORT).show();
    } // end else
} // end changePlayerState

public void nextMusic() {
    if (sMusicIndex == sMusicArray.length - 1) {
        sMusicIndex = 0;
    } else sMusicIndex++;
    mAnimator.cancel(); // 下一首取消动画
    mAnimator.start(); // 重新开始旋转
    updateMusicPlayer(sMusicIndex);
} // end nextMusic

public void stopMusic() {
    finish();
} // end stopMusic

到了这里,关于Android 音乐播放器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android课程设计大作业-音乐播放器

    1)使用Service播放音乐 Android SDK提供了Service。Service有两种类型: 本地服务(Local Service):用于应用程序内部 远程服务(Remote Sercie):用于Android系统内部的应用程序之间前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单

    2024年02月10日
    浏览(40)
  • Android手机开发课程设计之音乐播放器

    一、音乐播放器概述与分析 目前手机的音乐播放功能已经是大家比较关注的一个部分,不少在人在购买手机的时候都会关心手机的音乐播放的能力,这也足以看出目前大家对音乐播放功能的重视,所以一款性能良好的手机音乐播放器软件一定会受到欢迎。和传统的音乐播放器

    2024年02月05日
    浏览(51)
  • Android程序设计之音乐播放器实现

    基于MediaPlayer技术实现在线音乐播放器,播放在线音乐,后端使用SpringBoot将音乐存放在Tomcat服务器。app通过网络请求获取音乐,从而实现在线音乐播放。该项目分为用户端和管理员端 一、核心技术Service组件介绍 Service它可以在后台执行长时间运行操作而没有用户界面的应用组

    2024年02月04日
    浏览(54)
  • Android Studio初学者实例:仿网易音乐播放器

    本期带来的是以Service为主要的知识点的网易音乐播放器 看一下效果图  首先项目准备: 在res下新建raw文件夹,并在文件夹中添加喜爱的mp3音乐  OK,第一步,先写一个背景文件,在res/drawable文件夹中新建xml文件: btn_bg_selector.xml  编写主界面代码activity_main.xml 编写MusicServic

    2024年02月05日
    浏览(48)
  • Android Studio初学者实例:音乐播放器与Service学习

    本次一个案例实现的一个简单的音乐播放器 用到的知识点最主要的几点是:Service、handler(实现音乐播放的进度条更新与图片旋转)以及用于播放音频的MediaPlayer 看一下案例效果:  由于Service是Android的四大组件之一,Activity、Service等等一个重要知识点就是生命周期的问题,

    2024年02月03日
    浏览(45)
  • Android 13.0 系统多个播放器app时,设置默认播放器

     在13.0的系统产品开发中,对于在系统中有多个播放器的时候,这时候如果调用代码打开播放器,会出现多个播放器列表让用户 选择启动哪个播放器,所以产品开发需求需要设置默认播放器,当打开播放器的时候,就直接打开播放器就可以了,所以就需要 了解查询播放器列

    2024年02月08日
    浏览(67)
  • Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器

    Android 中封装优雅的 MediaPlayer 音频播放器,支持多个播放器实例的示例: 上述代码中,使用 getInstance() 方法获取 AudioPlayer 的单例对象,参数传入 Context 对象。 在 getInstance() 方法中判断单例对象是否为空,如果为空则创建新的 AudioPlayer 对象,否则返回已有的单例对象。 这样

    2024年02月12日
    浏览(46)
  • Android开发之视频播放器

    今天教大家做一个简单的视频播放器hh 至此,结束!

    2023年04月09日
    浏览(50)
  • Android学习6——视频播放器

    一、学习目标 1. 综合应用课程知识。 2. 掌握 App 开发流程及相关工具。 3. 设计 一个基于 Android 平台的简单视频播放器。 二、环境 1.JDK-15.0.2 以上 2.Android Studio 4.1 以上 3.Android 10.0 ( API level 29 ) 三、内容 软件功能简介 (1) 能够播放 3gp, .mp4 等文件; (2) 能处理简单的异常,例

    2024年02月01日
    浏览(83)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包