1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > Android应用开发--MP3音乐播放器滚动歌词实现

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

时间:2019-04-13 23:56:55

相关推荐

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

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

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

-----前话

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

-----主题

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

要的效果如下:

----实现过程

1. 建立歌词内容实体类

2. 自定义View

3. 加入布局文件

4. 编写歌词处理类

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

----代码实现

--LrcContent.java

package com.wwj.sb.domain;/*** /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;/*** /6/1* @authorwwj*处理歌词的类*/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;}

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。