服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - android实现歌词自动滚动效果

android实现歌词自动滚动效果

2022-08-16 10:28javaxinkule Android

这篇文章主要为大家详细介绍了android实现歌词自动滚动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

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

先上一下效果图:

android实现歌词自动滚动效果

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

代码如下 LyricView,相关信息在注释了标明了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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

延伸 · 阅读

精彩推荐