android实现歌词自动滚动效果
程序员文章站
2023-11-09 13:18:58
最近在做android 的mp3播放的项目,要实现歌词的自动滚动,以及同步显示。
lyric的歌词解析主要用yoyoplayer里面的,显示部分参考了 ,这里只是模拟mp...
最近在做android 的mp3播放的项目,要实现歌词的自动滚动,以及同步显示。
lyric的歌词解析主要用yoyoplayer里面的,显示部分参考了 ,这里只是模拟mp3歌词的滚动。
先上一下效果图:
滚动实现的代码其实也简单。显示画出当前时间点的歌词,然后再分别画出改歌词后面和前面的歌词,前面的部分往上推移,后面的部分往下推移,这样就保持了当前时间歌词在中间。
代码如下 lyricview,相关信息在注释了标明了。
package ru.org.piaozhiye.lyric; import java.io.file; import java.util.list; import android.content.context; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.path; import android.graphics.typeface; import android.util.attributeset; import android.widget.textview; /** * @author root * */ public class lyricview extends textview { private paint mpaint; private float mx; private static lyric mlyric; private paint mpathpaint; public string test = "test"; public int index = 0; private list<sentence> list; public float mtouchhistoryy; private int my; private long currentdunringtime; // 当前行歌词持续的时间,用该时间来sleep private float middley;// y轴中间 private static final int dy = 50; // 每一行的间隔 public lyricview(context context) { super(context); init(); } public lyricview(context context, attributeset attr) { super(context, attr); init(); } public lyricview(context context, attributeset attr, int i) { super(context, attr, i); init(); } private void init() { setfocusable(true); playlistitem pli = new playlistitem("because of you", "/sdcard/mp3/because of you.mp3", 0l, true); mlyric = new lyric(new file("/sdcard/mp3/because of you.lrc"), pli); list = mlyric.list; // 非高亮部分 mpaint = new paint(); mpaint.setantialias(true); mpaint.settextsize(22); mpaint.setcolor(color.white); mpaint.settypeface(typeface.serif); // 高亮部分 当前歌词 mpathpaint = new paint(); mpathpaint.setantialias(true); mpathpaint.setcolor(color.red); mpathpaint.settextsize(22); mpathpaint.settypeface(typeface.sans_serif); } protected void ondraw(canvas canvas) { super.ondraw(canvas); canvas.drawcolor(0xefeffff); paint p = mpaint; paint p2 = mpathpaint; p.settextalign(paint.align.center); if (index == -1) return; p2.settextalign(paint.align.center); // 先画当前行,之后再画他的前面和后面,这样就保持当前行在中间的位置 canvas.drawtext(list.get(index).getcontent(), mx, middley, p2); float tempy = middley; // 画出本句之前的句子 for (int i = index - 1; i >= 0; i--) { // sentence sen = list.get(i); // 向上推移 tempy = tempy - dy; if (tempy < 0) { break; } canvas.drawtext(list.get(i).getcontent(), mx, tempy, p); // canvas.translate(0, dy); } tempy = middley; // 画出本句之后的句子 for (int i = index + 1; i < list.size(); i++) { // 往下推移 tempy = tempy + dy; if (tempy > my) { break; } canvas.drawtext(list.get(i).getcontent(), mx, tempy, p); // canvas.translate(0, dy); } } protected void onsizechanged(int w, int h, int ow, int oh) { super.onsizechanged(w, h, ow, oh); mx = w * 0.5f; // remember the center of the screen my = h; middley = h * 0.5f; } // /** * @param time * 当前歌词的时间轴 * * @return currentdunringtime 歌词只需的时间 */ public long updateindex(long time) { // 歌词序号 index = mlyric.getnowsentenceindex(time); if (index == -1) return -1; sentence sen = list.get(index); // 返回歌词持续的时间,在这段时间内sleep return currentdunringtime = sen.getduring(); } }
剩下的就是使用他了。就是取出歌词的index,和该行歌词持续的时间进行sleep。
package ru.org.piaozhiye; import java.io.ioexception; import ru.org.piaozhiye.lyric.lyricview; import android.app.activity; import android.media.mediaplayer; import android.os.bundle; import android.os.handler; public class lyricdemo extends activity { private mediaplayer mp; private lyricview lyricview; private string path = "/sdcard/mp3/because of you.mp3"; /** called when the activity is first created. */ @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.main); lyricview = (lyricview) findviewbyid(r.id.audio_lrc); mp = new mediaplayer(); mp.reset(); try { mp.setdatasource(path); mp.prepare(); } catch (illegalargumentexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (illegalstateexception e) { // todo auto-generated catch block e.printstacktrace(); } catch (ioexception e) { // todo auto-generated catch block e.printstacktrace(); } mp.start(); new thread(new uiupdatethread()).start(); } class uiupdatethread implements runnable { long time = 100; // 开始 的时间,不能为零,否则前面几句歌词没有显示出来 public void run() { while (mp.isplaying()) { long sleeptime = lyricview.updateindex(time); time += sleeptime; mhandler.post(mupdateresults); if (sleeptime == -1) return; try { thread.sleep(sleeptime); } catch (interruptedexception e) { // todo auto-generated catch block e.printstacktrace(); } } } } handler mhandler = new handler(); runnable mupdateresults = new runnable() { public void run() { lyricview.invalidate(); // 更新视图 } }; }
整个project的源码。包括yoyoplayer的解析lyric部分代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Android中的相对路径实例详解
下一篇: Kotlin中的反射机制深入讲解