android实现歌词自动滚动效果

作者:javaxinkule 时间:2022-03-16 17:09:10 

最近在做Android 的MP3播放的项目,要实现歌词的自动滚动,以及同步显示。

lyric的歌词解析主要用yoyoplayer里面的,显示部分参考了这里 ,这里只是模拟MP3歌词的滚动。

先上一下效果图:

android实现歌词自动滚动效果

滚动实现的代码其实也简单。显示画出当前时间点的歌词,然后再分别画出改歌词后面和前面的歌词,前面的部分往上推移,后面的部分往下推移,这样就保持了当前时间歌词在中间。

代码如下 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部分代码。

来源:https://blog.csdn.net/javaxinkule/article/details/53224896

标签:android,滚动
0
投稿

猜你喜欢

  • C#中DataTable和List互转的示例代码

    2022-08-25 21:40:06
  • IDEA安装后找不到.vmoptions文件的问题及解决

    2023-10-05 22:43:44
  • Android开发登陆案例

    2022-03-19 10:13:01
  • Java InheritableThreadLocal用法详细介绍

    2023-01-27 04:30:11
  • Unity Shader实现新手引导遮罩镂空效果

    2022-08-18 16:25:12
  • Spring Boot利用JSR303实现参数验证的方法实例

    2022-07-28 20:36:26
  • Android滑动到顶部和底部时出现的阴影如何去掉

    2023-10-09 15:09:17
  • Android连接服务器端的Socket的实例代码

    2023-03-11 06:06:47
  • linux系统 java环境变量的配置方法

    2022-12-10 09:34:11
  • Java用邻接矩阵存储图的示例代码

    2021-10-05 21:39:18
  • MyBatis的 config.xml标签

    2021-07-18 02:01:34
  • 详解java开发webservice的几种方式

    2023-03-13 04:31:33
  • dubbo如何实现consumer从多个group中调用指定group的provider

    2022-06-09 01:00:13
  • C#实现winform渐变效果的方法

    2023-03-14 00:26:06
  • Android百度地图应用之基本地图功能实现

    2022-11-20 07:01:41
  • Spring Cloud Gateway 记录请求应答数据日志操作

    2021-12-27 07:25:53
  • C#操作DataGridView设置单元格只读

    2023-12-22 15:05:26
  • 使用logback屏蔽一些包的日志

    2023-08-08 20:46:20
  • 详解Java中的封装、继承、多态

    2022-09-24 06:26:23
  • C#异步使用需要注意的几个问题

    2023-03-05 04:33:08
  • asp之家 软件编程 m.aspxhome.com