最近在做android 的MP3播放的项目,要实现歌词的自动滚动,以及同步显示。
lyric的歌词解析主要用yoyoplayer里面的,
显示部分参考了http://ishelf.iteye.com/blog/740402 ,这里只是模拟MP3歌词的滚动。
先上一下效果图:
滚动实现的代码其实也简单。显示画出当前时间点的歌词,然后再分别画出改歌词后面和前面的歌词,前面的部分往上推移,后面的部分往下推移,这样就保持了当前时间歌词在中间。
代码如下 LyricView,相关信息在注释了标明了。
view plain copy to clipboard print ?
1. package
2. import
3. import
4. import
5. import
6. import
7. import
8. import
9. import
10. import
11. import
12. /**
13. * @author root
14. *
15. */
16. public class LyricView extends
17. private
18. private float
19. private static
20. private
21. public String test = "test"
22. public int index = 0
23. private
24. public float
25. private int
26. private long currentDunringTime; // 当前行歌词持续的时间,用该时间来sleep
27. private float middleY;// y轴中间
28. private static final int DY = 50 ; // 每一行的间隔
29. public
30. super
31. init();
32. }
33. public
34. super
35. init();
36. }
37. public LyricView(Context context, AttributeSet attr, int
38. super
39. init();
40. }
41. private void
42. true
43. new PlayListItem("Because Of You"
44. "/sdcard/MP3/Because Of You.mp3" , 0L, true
45. new Lyric(new File("/sdcard/MP3/Because Of You.lrc"
46. list = mLyric.list;
47. // 非高亮部分
48. new
49. true
50. 22
51. mPaint.setColor(Color.WHITE);
52. mPaint.setTypeface(Typeface.SERIF);
53. // 高亮部分 当前歌词
54. new
55. true
56. mPathPaint.setColor(Color.RED);
57. 22
58. mPathPaint.setTypeface(Typeface.SANS_SERIF);
59. }
60. protected void
61. super
62. 0xEFeffff
63. Paint p = mPaint;
64. Paint p2 = mPathPaint;
65. p.setTextAlign(Paint.Align.CENTER);
66. if (index == -1
67. return
68. p2.setTextAlign(Paint.Align.CENTER);
69. // 先画当前行,之后再画他的前面和后面,这样就保持当前行在中间的位置
70. canvas.drawText(list.get(index).getContent(), mX, middleY, p2);
71. float
72. // 画出本句之前的句子
73. for (int i = index - 1 ; i >= 0
74. // Sentence sen = list.get(i);
75. // 向上推移
76. tempY = tempY - DY;
77. if (tempY < 0
78. break
79. }
80. canvas.drawText(list.get(i).getContent(), mX, tempY, p);
81. // canvas.translate(0, DY);
82. }
83. tempY = middleY;
84. // 画出本句之后的句子
85. for (int i = index + 1
86. // 往下推移
87. tempY = tempY + DY;
88. if
89. break
90. }
91. canvas.drawText(list.get(i).getContent(), mX, tempY, p);
92. // canvas.translate(0, DY);
93. }
94. }
95. protected void onSizeChanged(int w, int h, int ow, int
96. super
97. 0 .5f; // remember the center of the screen
98. mY = h;
99. 0
100. }
101. //
102. /**
103. * @param time
104. * 当前歌词的时间轴
105. *
106. * @return currentDunringTime 歌词只需的时间
107. */
108. public long updateIndex(long
109. // 歌词序号
110. index = mLyric.getNowSentenceIndex(time);
111. if (index == -1
112. return -1
113. Sentence sen = list.get(index);
114. // 返回歌词持续的时间,在这段时间内sleep
115. return
116. }
117. }
剩下的就是使用他了。就是取出歌词的index,和该行歌词持续的时间进行sleep。
view plain copy to clipboard print ?
1. package ru.org.piaozhiye;
2. import java.io.IOException;
3. import ru.org.piaozhiye.lyric.LyricView;
4. import android.app.Activity;
5. import android.media.MediaPlayer;
6. import android.os.Bundle;
7. import android.os.Handler;
8. public class
9. private
10. private
11. private String path = "/sdcard/MP3/Because Of You.mp3"
12. /** Called when the activity is first created. */
13. @Override
14. public void
15. super.onCreate(savedInstanceState);
16. setContentView(R.layout.main);
17. lyricView = (LyricView) findViewById(R.id.audio_lrc);
18. new
19. mp.reset();
20. try
21. mp.setDataSource(path);
22. mp.prepare();
23. catch
24. // TODO Auto-generated catch block
25. e.printStackTrace();
26. catch
27. // TODO Auto-generated catch block
28. e.printStackTrace();
29. catch
30. // TODO Auto-generated catch block
31. e.printStackTrace();
32. }
33. mp.start();
34. new Thread(new
35. }
36. class
37. long time = 100; // 开始 的时间,不能为零,否则前面几句歌词没有显示出来
38. public void
39. while
40. long
41. time += sleeptime;
42. mHandler.post(mUpdateResults);
43. if
44. return
45. try
46. Thread.sleep(sleeptime);
47. catch
48. // TODO Auto-generated catch block
49. e.printStackTrace();
50. }
51. }
52. }
53. }
54. new
55. new
56. public void
57. // 更新视图
58. }
59. };
60. }
整个project的源码。包括yoyoplayer的解析lyric部分代码。