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

2013年6月2日  简、美音乐播放器开发记录

-----前话

有网友给我博客评论说,让我借鉴好的Android代码,代码贴出来的时候最好整体先看一下。其实小巫也有参考过别人的代码,主要是具体看某一个功能是怎么实现的,但是因为开发的思路不一样,只能说自己去写一些符合自己思路的代码。编写代码过程中,或多或少有纰漏之处,但基本上能实现功能就行了。小巫的功底还不够,不具备很强的重构代码的能力,一直都是以最直观的想法来编程,并没有太过关注性能的优化啥的,因为我也没发现自己开发的这款音乐播放器用起来不爽。不过,小巫会一直学习的,努力提升自己的编程水平,争取生产出优美的代码供朋友们参考。

-----主题

这篇博客的主题是:“滚动歌词的实现”

要的效果如下:

           

----实现过程

1. 建立歌词内容实体类

2. 自定义View

3. 加入布局文件

4. 编写歌词处理类

5. 在Service里面实现同步更新歌词

----代码实现

--LrcContent.java

package com.wwj.sb.domain;
/*** 2013/6/1* @author wwj* 歌词实体类*/
public class LrcContent {private String lrcStr; //歌词内容private int lrcTime;  //歌词当前时间public String getLrcStr() {return lrcStr;}public void setLrcStr(String lrcStr) {this.lrcStr = lrcStr;}public int getLrcTime() {return lrcTime;}public void setLrcTime(int lrcTime) {this.lrcTime = lrcTime;}
}

--LrcView.java

package com.wwj.sb.custom;import java.util.ArrayList;
import java.util.List;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;import com.wwj.sb.domain.LrcContent;/*** 自定义绘画歌词,产生滚动效果* @author wwj**/
public class LrcView extends android.widget.TextView {private float width;      //歌词视图宽度private float height;       //歌词视图高度private Paint currentPaint; //当前画笔对象private Paint notCurrentPaint;  //非当前画笔对象private float textHeight = 25;    //文本高度private float textSize = 18;     //文本大小private int index = 0;       //list集合下标private List<LrcContent> mLrcList = new ArrayList<LrcContent>();public void setmLrcList(List<LrcContent> mLrcList) {this.mLrcList = mLrcList;}public LrcView(Context context) {super(context);init();}public LrcView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}public LrcView(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {setFocusable(true);      //设置可对焦//高亮部分currentPaint = new Paint();currentPaint.setAntiAlias(true);   //设置抗锯齿,让文字美观饱满currentPaint.setTextAlign(Paint.Align.CENTER);//设置文本对齐方式//非高亮部分notCurrentPaint = new Paint();notCurrentPaint.setAntiAlias(true);notCurrentPaint.setTextAlign(Paint.Align.CENTER);}/*** 绘画歌词*/@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);if(canvas == null) {return;}currentPaint.setColor(Color.argb(210, 251, 248, 29));notCurrentPaint.setColor(Color.argb(140, 255, 255, 255));currentPaint.setTextSize(24);currentPaint.setTypeface(Typeface.SERIF);notCurrentPaint.setTextSize(textSize);notCurrentPaint.setTypeface(Typeface.DEFAULT);try {setText("");canvas.drawText(mLrcList.get(index).getLrcStr(), width / 2, height / 2, currentPaint);float tempY = height / 2;//画出本句之前的句子for(int i = index - 1; i >= 0; i--) {//向上推移tempY = tempY - textHeight;canvas.drawText(mLrcList.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint);}tempY = height / 2;//画出本句之后的句子for(int i = index + 1; i < mLrcList.size(); i++) {//往下推移tempY = tempY + textHeight;canvas.drawText(mLrcList.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint);} } catch (Exception e) {setText("...木有歌词文件,赶紧去下载...");}}/*** 当view大小改变的时候调用的方法*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);this.width = w;this.height = h;}public void setIndex(int index) {this.index = index;}}

--LrcProcess.java

package com.wwj.sb.custom;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;import android.util.Xml.Encoding;
import android.widget.SlidingDrawer;import com.wwj.sb.domain.LrcContent;/*** 2013/6/1* @author wwj*    处理歌词的类*/
public class LrcProcess {private List<LrcContent> lrcList;    //List集合存放歌词内容对象private LrcContent mLrcContent;     //声明一个歌词内容对象/*** 无参构造函数用来实例化对象*/public LrcProcess() {mLrcContent = new LrcContent();lrcList = new ArrayList<LrcContent>();}/*** 读取歌词* @param path* @return*/public String readLRC(String path) {//定义一个StringBuilder对象,用来存放歌词内容StringBuilder stringBuilder = new StringBuilder();File f = new File(path.replace(".mp3", ".lrc"));try {//创建一个文件输入流对象FileInputStream fis = new FileInputStream(f);InputStreamReader isr = new InputStreamReader(fis, "utf-8");BufferedReader br = new BufferedReader(isr);String s = "";while((s = br.readLine()) != null) {//替换字符s = s.replace("[", "");s = s.replace("]", "@");//分离“@”字符String splitLrcData[] = s.split("@");if(splitLrcData.length > 1) {mLrcContent.setLrcStr(splitLrcData[1]);//处理歌词取得歌曲的时间int lrcTime = time2Str(splitLrcData[0]);mLrcContent.setLrcTime(lrcTime);//添加进列表数组lrcList.add(mLrcContent);//新创建歌词内容对象mLrcContent = new LrcContent();}}} catch (FileNotFoundException e) {e.printStackTrace();stringBuilder.append("木有歌词文件,赶紧去下载!...");} catch (IOException e) {e.printStackTrace();stringBuilder.append("木有读取到歌词哦!");}return stringBuilder.toString();}/*** 解析歌词时间* 歌词内容格式如下:* [00:02.32]陈奕迅* [00:03.43]好久不见* [00:05.22]歌词制作  王涛* @param timeStr* @return*/public int time2Str(String timeStr) {timeStr = timeStr.replace(":", ".");timeStr = timeStr.replace(".", "@");String timeData[] = timeStr.split("@"); //将时间分隔成字符串数组//分离出分、秒并转换为整型int minute = Integer.parseInt(timeData[0]);int second = Integer.parseInt(timeData[1]);int millisecond = Integer.parseInt(timeData[2]);//计算上一行与下一行的时间转换为毫秒数int currentTime = (minute * 60 + second) * 1000 + millisecond * 10;return currentTime;}public List<LrcContent> getLrcList() {return lrcList;}
}

加入布局文件:

 <com.wwj.sb.custom.LrcViewandroid:id="@+id/lrcShowView"android:layout_width="match_parent"android:layout_height="200dip"android:layout_above="@+id/footer_layout"android:layout_below="@+id/header_layout"android:layout_centerHorizontal="true" />

--在Service.java中的实现,这里就不贴完整的Service类了,主要是如何在Service实现歌词同步的。

声明变量:

private LrcProcess mLrcProcess;  //歌词处理
private List<LrcContent> lrcList = new ArrayList<LrcContent>(); //存放歌词列表对象
private int index = 0;         //歌词检索值

核心实现代码:

 /*** 初始化歌词配置*/public void initLrc(){mLrcProcess = new LrcProcess();//读取歌词文件mLrcProcess.readLRC(mp3Infos.get(current).getUrl());//传回处理后的歌词文件lrcList = mLrcProcess.getLrcList();PlayerActivity.lrcView.setmLrcList(lrcList);//切换带动画显示歌词PlayerActivity.lrcView.setAnimation(AnimationUtils.loadAnimation(PlayerService.this,R.anim.alpha_z));handler.post(mRunnable);}Runnable mRunnable = new Runnable() {@Overridepublic void run() {PlayerActivity.lrcView.setIndex(lrcIndex());PlayerActivity.lrcView.invalidate();handler.postDelayed(mRunnable, 100);}};
 /*** 根据时间获取歌词显示的索引值* @return*/public int lrcIndex() {if(mediaPlayer.isPlaying()) {currentTime = mediaPlayer.getCurrentPosition();duration = mediaPlayer.getDuration();}if(currentTime < duration) {for (int i = 0; i < lrcList.size(); i++) {if (i < lrcList.size() - 1) {if (currentTime < lrcList.get(i).getLrcTime() && i == 0) {index = i;}if (currentTime > lrcList.get(i).getLrcTime()&& currentTime < lrcList.get(i + 1).getLrcTime()) {index = i;}}if (i == lrcList.size() - 1&& currentTime > lrcList.get(i).getLrcTime()) {index = i;}}}return index;}

其实,小巫还想实现可以拖动歌词来控制播放进度,还有自动搜索歌词等更加完备的实现。

Android应用开发--MP3音乐播放器滚动歌词实现相关推荐

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

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

  2. Android应用开发--MP3音乐播放器滚动歌词实现,flutter跳转动画

    2. 自定义View 3. 加入布局文件 4. 编写歌词处理类 5. 在Service里面实现同步更新歌词 ----代码实现 –LrcContent.java package com.wwj.sb.d ...

  3. android开发歌词滑动效果_Android应用开发--MP3音乐播放器滚动歌词实现

    [android]代码库2013年6月2日 简.美音乐播放器开发记录 -----主题 这篇博客的主题是:"滚动歌词的实现" 要的效果如下: ----实现过程 1. 建立歌词内容实体 ...

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

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

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

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

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

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

  7. Android应用开发--MP3音乐播放器代码实现(二,android开发实例大全

    } switch (repeatState) { case isCurrentRepeat: // 单曲循环 repeatBtn .setBackgroundResource(R.drawable.r ...

  8. 音乐应用开发Android应用开发--MP3音乐播放器界面设计(2)

    在写这篇文章之前,xxx已写过了几篇关于改音乐应用开发主题的文章,想要了解的朋友可以去翻一下之前的文章 Android应用开发--MP3音乐播放器界面计划(2) 2013年5月25日 简.美音乐播放器 ...

  9. Android应用开发--MP3音乐播放器界面设计(2)

    Android应用开发--MP3音乐播放器界面设计(2) 2013年5月25日 简.美音乐播放器开发 真得很无奈,原本打算很快结束这个实战项目的,但因为各种满课.学科.杂事给耽误了进度,现在小巫的这个 ...

最新文章

  1. 【Python】青少年蓝桥杯_每日一题_7.03_输出符合要求的字母
  2. gevent-tutorial翻译和解读
  3. linux 蓝牙攻击,研究人员担心BleedingTooth蓝牙漏洞给Linux系统带来风险
  4. MyBatis 使用
  5. php手机号批量分类,一个非常好的php实现手机号归属地查询接口类
  6. 【电脑控制手机屏幕】windows11、10自带投屏功能,三步解决
  7. 【CG物理模拟系列】流体模拟--粒子法之MPS法(理论)
  8. 家谱排版制作软件怎么三步成谱
  9. 基于CTP的国内期货程序化交易之行情获取讲解
  10. java版怎么安装mod_java – 如何在Mac OS X上安装mod_jk
  11. 8款炫酷的HTML5特效源码
  12. ajaxtoolkit
  13. css sprite与background-size结合实现背景图片等比缩放
  14. ChatGPT替代品使用指南
  15. 计算机操作系统-文件管理
  16. 《微观经济学》 第三章
  17. Java的wait()、notify()学习三部曲之一:JVM源码分析
  18. 《深入理解Java虚拟机(第2版)》-笔记
  19. JavaScript 解决计算误差
  20. C++圆的面积与周长 自定义函数

热门文章

  1. 电信网上营业厅用户自服务系统的设计与实现
  2. Oracle魔改linux,linux shell脚本攻略 第3版 pdfssr 魔改v3一键
  3. linux ipv6添加路由器,使用Linux搭建IPV6路由器(CentOS版)
  4. 微信小程序之时间计算器
  5. FBX与Opengl骨骼系统
  6. RTE2020首批嘉宾公布 技术+行业专家携手顶级投资人参会
  7. 被关在寝室的某个下午
  8. nodejs使用addon调用c/c++
  9. 商业虚拟专用网络技术十三 BGP/MPLS报文转发
  10. windows mysql提示:1045 access denied for user 'root'@'localhost' using password ye