歌词展示
封装歌词信息
歌词的内容如下,一行歌词由两部分组成,[]里面的是开始时间,后面的是歌词内容
|
|
对应的实体类为
|
|
绘制单行居中文本
自定义一个显示歌词的LyricView,歌词本身就是一个文本,所以在这里我们继承TextView。它还有一个好处继承TextView 之后不需要再去重写onMeasure 方法。在onDraw 方法中去绘制一个文本。
|
|
在项目中的歌词布局中引用View,重新build 之后的展示效果
从上图中可以看到文本显示的坐标是view 的左上角。那么我们需要将文本显示的位置设置在view 的中间。计算的方法如图
在onSizeChang 中计算出View 宽和高的一半,通过paint.getTextBounds 方法计算出文本的宽高的一半。
|
|
重新build 之后的效果如下:
但是在Android Studio中使用bounds.width 方法获取的文本宽度设置之后不在View 的中间。所以我们使用了paint.getTextMeasure(text)来重新获取
|
|
绘制多行歌词
首先用List 模拟歌词的数据并且记录高亮行的行数。
|
|
获取高亮行的位置。
|
|
按行绘制文本。
|
|
y=居中行y 的位置+(绘制行的位置-高亮行的行数)*行高。
|
|
x=水平居中的x。
|
|
效果图如下
按行滚动歌词
在LyricView 中提供一个滚动歌词的方法。说白了其实只要设置歌词高亮的位置就可以了。设置歌词高亮的位置的算法如图
|
|
在音乐播放界面中发消息让歌词滚动。在接收到准备完成的广播之后就让歌词开始滚动。
|
|
平滑滚动歌词
平滑滚动歌词的算法如图
计算时使用的已播放时间和播放总时间需要从roll 方法中获取
|
|
运行结果
从文件中解析歌词
从文件中解析歌词。将歌词一行一行的读出来,并且根据歌词的格式解析成List 集合,并将歌词排序。
|
|
需要实现Comparable 接口,实现compareTo 方法
|
|
在LyricView 中提供从文件中获取歌词集合和设置当前高亮行的方法。
|
|
在onDraw 方法中绘制的时候,需要去判断集合是否有数据,没有数据的话就显示歌词正在加载中,如果有数据的话就显示歌词。
|
|
在接收准备的广播中的滚动歌词之前将歌词加载出来。
|
|
运行结果
歌词加载模块
我们发现北京北京的歌词没有加载出来。是因为上面我们传的文件时lrc 后缀的文件,但如图北京北京的歌词的后缀是txt,所以在这里我们需要写一个歌词加载器。当文件中没有lrc 后缀的歌词的时候,就看看有没有txt 后缀的歌词,如果都没有的话需要从服务器下载。
|
|
在播放界面收到广播之后调用方法初始化歌词文件。
|
|
运行结果
小结
本篇博客完成了音乐播放界面的歌词展示,自定义了展示歌词的控件,先在控件中间显示一行文字,然后又显示了集合中的所有文字。接着通过改变当前高亮显示的行数来使歌词移动起来。我们通过设置偏移量让歌词的移动看起来更平滑。最后从文件中将歌词解析出来。但是我们为了能够适应txt 和lrc 文件格式的歌词文件,自定义了一个歌词加载器。当文件中没有lrc 后缀的歌词的时候,就看看有没有txt 后缀的歌词,如果都没有的话需要从服务器下载