小项目开发——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-813244.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音乐播放器的设计

    本科毕业论文(设计)诚信声明 本人郑重声明:所呈交的毕业论文(设计),题目《………基于android音乐播放器的设计……………………………》是本人在指导教师的指导下,进行研究工作所取得的成果。对本文的研究作出重要贡献的个人和集体,均已在文章以明确方式注

    2024年02月03日
    浏览(34)
  • Android课程设计大作业-音乐播放器

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

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

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

    2024年02月04日
    浏览(43)
  • FPGA开发:音乐播放器

    相关阅读  FPGA开发专栏 https://blog.csdn.net/weixin_45791458/category_12388695.html?spm=1001.2014.3001.5482         FPGA开发板上的蜂鸣器可以用来播放音乐,只需要控制蜂鸣器信号的方波频率、占空比和持续时间即可。         简谱上的4/4表示该简谱以4分音符为一拍,每小节4拍,简谱上应该

    2024年02月14日
    浏览(29)
  • 《微信小程序》音乐播放器项目

    需求:在装有node.js的机器上使用微信开发者工具开发一个音乐播放项目 写这个项目的时候电脑前后蓝屏了5次,制作不易,希望大佬们给个双击,顺子在这感谢啦! 展示: pages–index–index.js 01.png 02.png 02stop.png 03.png 04.png 05.png 06.png banner.jpg banner2.jpg banner3.jpg cover.jpg cover1.png

    2024年02月11日
    浏览(35)
  • 项目7-音乐播放器6+评论区

    前端小白:怎么为你的网页增加评论功能?(一)_为网页添加评论区怎么弄-CSDN博客 参考的上述文章的前端代码 我们从上述前端图片知道,我们数据库需要准备的字段: id,commentuserName,coomentmusicId,comment,time 路径:\\\"/comment/upload\\\" 1.MAPPER 2.SERVICE 3.Controller MAPPER SERVICE CONTROLLER 成功

    2024年04月23日
    浏览(58)
  • 项目7-音乐播放器2(上传音乐+查询音乐+拦截器)

    之后就不用对用户是否登录进行判断了 生效 请求: { post, /music/upload {singer,MultipartFile file}, } 响应: { \\\"status\\\": 0, \\\"message\\\": \\\"上传成功!\\\", \\\"data\\\": true } Java如何判断一个文件是否为真实的MP3文件_判断一个文件是否是mp3 文件-CSDN博客 流程:前端进行相关的文件操作-再将上传的文

    2024年04月17日
    浏览(30)
  • HarmonyOS开发案例:【音乐播放器】

    使用ArkTS语言实现了一个简易的音乐播放器应用,主要包含以下功能: 播放应用中的音频资源文件,并可进行上一曲、下一曲、播放、暂停、切换播放模式(顺序播放、单曲循环、随机播放)等操作。 结合后台任务管理模块,实现熄屏后继续播放音频。 相关概念 [AVPlayer]:

    2024年04月24日
    浏览(34)
  • 完整实例项目:使用python自制音乐播放器~

    今天使用python的pygame等模块制作了一个简单的音乐播放器,实现了很多好玩的功能,在这里和大家一起分享!这是笔者的第二篇博客,也是正式的完成一个小项目,希望获得大家的支持~ 暂停、继续播放、调整声音大小、上一曲下一曲调整、无限制追加音乐(但需要下载音乐

    2024年02月11日
    浏览(32)
  • 微信小程序仿网易音乐播放器项目

    主页样式 播放页样式 搜索页样式 排行榜页样式 小控件样式 网易云音乐API接口 后端接口,使用node写的,使用了网易云音乐API: 封装的api文件 主页面功能点 banner,滑动菜单栏采用微信的API( swiper 与 scroll-view )进行开发 滑动到底部重新获取后续的歌曲,使用onReachBottom周期

    2024年02月06日
    浏览(27)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包