android实现歌词自动滚动效果

最近在做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实现歌词自动滚动效果 的全部内容, 来源链接: utcz.com/z/350920.html

回到顶部