3 | # Encoding is UTF-8
4 |
--------------------------------------------------------------------------------
/OpenLRC/bin/res/crunch/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/bin/res/crunch/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/bin/res/crunch/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/bin/res/crunch/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/bin/res/crunch/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/bin/res/crunch/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/bin/res/crunch/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/bin/res/crunch/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/bin/resources.ap_:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/bin/resources.ap_
--------------------------------------------------------------------------------
/OpenLRC/gen/org/load/lrcviewtest/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package org.load.lrcviewtest;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/OpenLRC/gen/org/load/lrcviewtest/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package org.load.lrcviewtest;
9 |
10 | public final class R {
11 | public static final class attr {
12 | /** May be a reference to another resource, in the form "@[+][package:]type:name
"
13 | or to a theme attribute in the form "?[package:][type:]name
".
14 |
May be a color value, in the form of "#rgb
", "#argb
",
15 | "#rrggbb
", or "#aarrggbb
".
16 | */
17 | public static final int currentTextColor=0x7f010002;
18 | /**
Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp
".
19 | Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
20 | in (inches), mm (millimeters).
21 |
This may also be a reference to a resource (in the form
22 | "@[package:]type:name
") or
23 | theme attribute (in the form
24 | "?[package:][type:]name
")
25 | containing a value of this type.
26 | */
27 | public static final int dividerHeight=0x7f010003;
28 | /**
May be a reference to another resource, in the form "@[+][package:]type:name
"
29 | or to a theme attribute in the form "?[package:][type:]name
".
30 |
May be a color value, in the form of "#rgb
", "#argb
",
31 | "#rrggbb
", or "#aarrggbb
".
32 | */
33 | public static final int normalTextColor=0x7f010001;
34 | /**
Must be an integer value, such as "100
".
35 |
This may also be a reference to a resource (in the form
36 | "@[package:]type:name
") or
37 | theme attribute (in the form
38 | "?[package:][type:]name
")
39 | containing a value of this type.
40 | */
41 | public static final int rows=0x7f010004;
42 | /**
Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp
".
43 | Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
44 | in (inches), mm (millimeters).
45 |
This may also be a reference to a resource (in the form
46 | "@[package:]type:name
") or
47 | theme attribute (in the form
48 | "?[package:][type:]name
")
49 | containing a value of this type.
50 | */
51 | public static final int textSize=0x7f010000;
52 | }
53 | public static final class dimen {
54 | /** Default screen margins, per the Android Design guidelines.
55 |
56 | Customize dimensions originally defined in res/values/dimens.xml (such as
57 | screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
58 |
59 | */
60 | public static final int activity_horizontal_margin=0x7f040000;
61 | public static final int activity_vertical_margin=0x7f040001;
62 | }
63 | public static final class drawable {
64 | public static final int ic_launcher=0x7f020000;
65 | }
66 | public static final class id {
67 | public static final int action_settings=0x7f080001;
68 | public static final int lrc=0x7f080000;
69 | }
70 | public static final class layout {
71 | public static final int activity_main=0x7f030000;
72 | }
73 | public static final class menu {
74 | public static final int main=0x7f070000;
75 | }
76 | public static final class string {
77 | public static final int action_settings=0x7f050001;
78 | public static final int app_name=0x7f050000;
79 | public static final int hello_world=0x7f050002;
80 | }
81 | public static final class style {
82 | /**
83 | Base application theme, dependent on API level. This theme is replaced
84 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
85 |
86 |
87 | Theme customizations available in newer API levels can go in
88 | res/values-vXX/styles.xml, while customizations related to
89 | backward-compatibility can go here.
90 |
91 |
92 | Base application theme for API 11+. This theme completely replaces
93 | AppBaseTheme from res/values/styles.xml on API 11+ devices.
94 |
95 | API 11 theme customizations can go here.
96 |
97 | Base application theme for API 14+. This theme completely replaces
98 | AppBaseTheme from BOTH res/values/styles.xml and
99 | res/values-v11/styles.xml on API 14+ devices.
100 |
101 | API 14 theme customizations can go here.
102 | */
103 | public static final int AppBaseTheme=0x7f060000;
104 | /** Application theme.
105 | All customizations that are NOT specific to a particular API-level can go here.
106 | */
107 | public static final int AppTheme=0x7f060001;
108 | }
109 | public static final class styleable {
110 | /** Attributes that can be used with a Lrc.
111 |
Includes the following attributes:
112 |
113 |
114 |
115 | Attribute | Description |
116 | {@link #Lrc_currentTextColor org.load.lrcviewtest:currentTextColor} | |
117 | {@link #Lrc_dividerHeight org.load.lrcviewtest:dividerHeight} | |
118 | {@link #Lrc_normalTextColor org.load.lrcviewtest:normalTextColor} | |
119 | {@link #Lrc_rows org.load.lrcviewtest:rows} | |
120 | {@link #Lrc_textSize org.load.lrcviewtest:textSize} | |
121 |
122 | @see #Lrc_currentTextColor
123 | @see #Lrc_dividerHeight
124 | @see #Lrc_normalTextColor
125 | @see #Lrc_rows
126 | @see #Lrc_textSize
127 | */
128 | public static final int[] Lrc = {
129 | 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003,
130 | 0x7f010004
131 | };
132 | /**
133 | This symbol is the offset where the {@link org.load.lrcviewtest.R.attr#currentTextColor}
134 | attribute's value can be found in the {@link #Lrc} array.
135 |
136 |
137 |
May be a reference to another resource, in the form "@[+][package:]type:name
"
138 | or to a theme attribute in the form "?[package:][type:]name
".
139 |
May be a color value, in the form of "#rgb
", "#argb
",
140 | "#rrggbb
", or "#aarrggbb
".
141 | @attr name org.load.lrcviewtest:currentTextColor
142 | */
143 | public static final int Lrc_currentTextColor = 2;
144 | /**
145 |
This symbol is the offset where the {@link org.load.lrcviewtest.R.attr#dividerHeight}
146 | attribute's value can be found in the {@link #Lrc} array.
147 |
148 |
149 |
Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp
".
150 | Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
151 | in (inches), mm (millimeters).
152 |
This may also be a reference to a resource (in the form
153 | "@[package:]type:name
") or
154 | theme attribute (in the form
155 | "?[package:][type:]name
")
156 | containing a value of this type.
157 | @attr name org.load.lrcviewtest:dividerHeight
158 | */
159 | public static final int Lrc_dividerHeight = 3;
160 | /**
161 |
This symbol is the offset where the {@link org.load.lrcviewtest.R.attr#normalTextColor}
162 | attribute's value can be found in the {@link #Lrc} array.
163 |
164 |
165 |
May be a reference to another resource, in the form "@[+][package:]type:name
"
166 | or to a theme attribute in the form "?[package:][type:]name
".
167 |
May be a color value, in the form of "#rgb
", "#argb
",
168 | "#rrggbb
", or "#aarrggbb
".
169 | @attr name org.load.lrcviewtest:normalTextColor
170 | */
171 | public static final int Lrc_normalTextColor = 1;
172 | /**
173 |
This symbol is the offset where the {@link org.load.lrcviewtest.R.attr#rows}
174 | attribute's value can be found in the {@link #Lrc} array.
175 |
176 |
177 |
Must be an integer value, such as "100
".
178 |
This may also be a reference to a resource (in the form
179 | "@[package:]type:name
") or
180 | theme attribute (in the form
181 | "?[package:][type:]name
")
182 | containing a value of this type.
183 | @attr name org.load.lrcviewtest:rows
184 | */
185 | public static final int Lrc_rows = 4;
186 | /**
187 |
This symbol is the offset where the {@link org.load.lrcviewtest.R.attr#textSize}
188 | attribute's value can be found in the {@link #Lrc} array.
189 |
190 |
191 |
Must be a dimension value, which is a floating point number appended with a unit such as "14.5sp
".
192 | Available units are: px (pixels), dp (density-independent pixels), sp (scaled pixels based on preferred font size),
193 | in (inches), mm (millimeters).
194 |
This may also be a reference to a resource (in the form
195 | "@[package:]type:name
") or
196 | theme attribute (in the form
197 | "?[package:][type:]name
")
198 | containing a value of this type.
199 | @attr name org.load.lrcviewtest:textSize
200 | */
201 | public static final int Lrc_textSize = 0;
202 | };
203 | }
204 |
--------------------------------------------------------------------------------
/OpenLRC/ic_launcher-web.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/ic_launcher-web.png
--------------------------------------------------------------------------------
/OpenLRC/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/OpenLRC/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/OpenLRC/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-14
15 |
--------------------------------------------------------------------------------
/OpenLRC/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/OpenLRC/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/OpenLRC/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
21 |
22 |
--------------------------------------------------------------------------------
/OpenLRC/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/OpenLRC/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OpenLRC/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/OpenLRC/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/OpenLRC/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/OpenLRC/res/values/attrs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/OpenLRC/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/OpenLRC/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | OpenLRC
5 | Settings
6 | Hello world!
7 |
8 |
9 |
--------------------------------------------------------------------------------
/OpenLRC/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/OpenLRC/src/org/load/main/MainActivity.java:
--------------------------------------------------------------------------------
1 | package org.load.main;
2 |
3 | import java.io.File;
4 |
5 | import org.load.lrcviewtest.R;
6 | import org.load.openlrc.LrcView;
7 |
8 | import android.app.Activity;
9 | import android.graphics.BitmapFactory;
10 | import android.media.MediaPlayer;
11 | import android.media.MediaPlayer.OnPreparedListener;
12 | import android.os.Bundle;
13 | import android.os.Environment;
14 |
15 | public class MainActivity extends Activity {
16 | private LrcView mLrc;
17 | private MediaPlayer mPlayer;
18 | private String mDir = Environment.getExternalStorageDirectory() + File.separator + "Download" + File.separator;
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 |
25 | // 歌曲路径
26 | String music = mDir + "1.mp3";
27 | // 歌词路径
28 | String lrc = mDir + "1.lrc";
29 |
30 | mLrc = (LrcView) findViewById(R.id.lrc);
31 | // 设置背景图片
32 | // 可以选择不设置
33 | // 最好是在真个屏幕设置该图片
34 | // 那样更好看
35 | mLrc.setBackground(BitmapFactory.decodeFile(mDir + "1.png"));
36 |
37 | mPlayer = new MediaPlayer();
38 | try {
39 | mPlayer.setDataSource(music);
40 | mPlayer.setOnPreparedListener(new PreparedListener());
41 | mPlayer.prepareAsync();
42 |
43 | // 设置lrc的路径
44 | mLrc.setLrcPath(lrc);
45 | } catch (Exception e) {
46 | e.printStackTrace();
47 | }
48 | }
49 |
50 | private class PreparedListener implements OnPreparedListener {
51 | @Override
52 | public void onPrepared(MediaPlayer mp) {
53 |
54 | mPlayer.start();
55 | new Thread(new Runnable() {
56 | @Override
57 | public void run() {
58 | // 当歌曲还在播放时
59 | // 就一直调用changeCurrent方法
60 | // 虽然一直调用, 但界面不会一直刷新
61 | // 只有当唱到下一句时才刷新
62 | while(mPlayer.isPlaying()) {
63 | // 调用changeCurrent方法, 参数是当前播放的位置
64 | // LrcView会自动判断需不需要下一行
65 | mLrc.changeCurrent(mPlayer.getCurrentPosition());
66 |
67 | // 当然这里还是要睡一会的啦
68 | try {
69 | Thread.sleep(100);
70 | } catch (InterruptedException e) {
71 | e.printStackTrace();
72 | }
73 | }
74 | }
75 | }).start();
76 | }
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/OpenLRC/src/org/load/openlrc/LrcView.java:
--------------------------------------------------------------------------------
1 | package org.load.openlrc;
2 |
3 | import java.io.BufferedReader;
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.InputStreamReader;
7 | import java.util.ArrayList;
8 | import java.util.List;
9 | import java.util.regex.Matcher;
10 | import java.util.regex.Pattern;
11 |
12 | import org.load.lrcviewtest.R;
13 |
14 | import android.annotation.SuppressLint;
15 | import android.content.Context;
16 | import android.content.res.TypedArray;
17 | import android.graphics.Bitmap;
18 | import android.graphics.Canvas;
19 | import android.graphics.Paint;
20 | import android.util.AttributeSet;
21 | import android.view.View;
22 |
23 | /**
24 | * 显示lrc歌词控件
25 | * @author 亓斌 (qibin@gmail.com)
26 | */
27 | @SuppressLint("DrawAllocation")
28 | public class LrcView extends View {
29 | private List mLrcs = new ArrayList(); // 存放歌词
30 | private List mTimes = new ArrayList(); // 存放时间
31 |
32 | private long mNextTime = 0l; // 保存下一句开始的时间
33 |
34 | private int mViewWidth; // view的宽度
35 | private int mLrcHeight; // lrc界面的高度
36 | private int mRows; // 多少行
37 | private int mCurrentLine = 0; // 当前行
38 |
39 | private float mTextSize; // 字体
40 | private float mDividerHeight; // 行间距
41 |
42 | private Paint mNormalPaint; // 常规的字体
43 | private Paint mCurrentPaint; // 当前歌词的大小
44 |
45 | private Bitmap mBackground = null;
46 |
47 | public LrcView(Context context, AttributeSet attrs) {
48 | super(context, attrs);
49 | initViews(attrs);
50 | }
51 |
52 | public LrcView(Context context, AttributeSet attrs, int defStyleAttr) {
53 | super(context, attrs, defStyleAttr);
54 | initViews(attrs);
55 | }
56 |
57 | // 初始化操作
58 | private void initViews(AttributeSet attrs) {
59 | //
60 | // 解析自定义属性
61 | TypedArray ta = getContext().obtainStyledAttributes(attrs,
62 | R.styleable.Lrc);
63 | mTextSize = ta.getDimension(R.styleable.Lrc_textSize, 50.0f);
64 | mRows = ta.getInteger(R.styleable.Lrc_rows, 5);
65 | mDividerHeight = ta.getDimension(R.styleable.Lrc_dividerHeight, 0.0f);
66 |
67 | int normalTextColor = ta.getColor(R.styleable.Lrc_normalTextColor,
68 | 0xffffffff);
69 | int currentTextColor = ta.getColor(R.styleable.Lrc_currentTextColor,
70 | 0xff00ffde);
71 |
72 | ta.recycle();
73 | //
74 |
75 | // 计算lrc面板的高度
76 | mLrcHeight = (int) (mTextSize + mDividerHeight) * mRows + 5;
77 |
78 | mNormalPaint = new Paint();
79 | mCurrentPaint = new Paint();
80 |
81 | // 初始化paint
82 | mNormalPaint.setTextSize(mTextSize);
83 | mNormalPaint.setColor(normalTextColor);
84 | mCurrentPaint.setTextSize(mTextSize);
85 | mCurrentPaint.setColor(currentTextColor);
86 | }
87 |
88 | @Override
89 | protected void onSizeChanged(int w, int h, int oldw, int oldh) {
90 | // 获取view宽度
91 | mViewWidth = getMeasuredWidth();
92 | super.onSizeChanged(w, h, oldw, oldh);
93 | }
94 |
95 | @Override
96 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
97 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
98 | // 重新设置view的高度
99 | int measuredHeight = MeasureSpec.makeMeasureSpec(mLrcHeight, MeasureSpec.AT_MOST);
100 | setMeasuredDimension(widthMeasureSpec, measuredHeight);
101 | }
102 |
103 | @Override
104 | protected void onDraw(Canvas canvas) {
105 | super.onDraw(canvas);
106 | if (mLrcs.isEmpty() || mTimes.isEmpty()) {
107 | return;
108 | }
109 |
110 | canvas.save();
111 | // 圈出可视区域
112 | canvas.clipRect(0, 0, mViewWidth, mLrcHeight);
113 |
114 | if (null != mBackground) {
115 | canvas.drawBitmap(Bitmap.createScaledBitmap(mBackground, mViewWidth, mLrcHeight, true),
116 | new android.graphics.Matrix(), null);
117 | }
118 |
119 | // 将画布上移
120 | canvas.translate(0, -((mCurrentLine - 3) * (mTextSize + mDividerHeight)));
121 |
122 | // 画当前行上面的
123 | for (int i = mCurrentLine - 1; i >= 0; i--) {
124 | String lrc = mLrcs.get(i);
125 | float x = (mViewWidth - mNormalPaint.measureText(lrc)) / 2;
126 | canvas.drawText(lrc, x, (mTextSize + mDividerHeight) * i,mNormalPaint);
127 | }
128 |
129 | String currentLrc = mLrcs.get(mCurrentLine);
130 | float currentX = (mViewWidth - mCurrentPaint.measureText(currentLrc)) / 2;
131 | // 画当前行
132 | canvas.drawText(currentLrc, currentX, (mTextSize + mDividerHeight)* mCurrentLine, mCurrentPaint);
133 |
134 | // 画当前行下面的
135 | for (int i = mCurrentLine + 1; i < mLrcs.size(); i++) {
136 | String lrc = mLrcs.get(i);
137 | float x = (mViewWidth - mNormalPaint.measureText(lrc)) / 2;
138 | canvas.drawText(lrc, x, (mTextSize + mDividerHeight) * i, mNormalPaint);
139 | }
140 |
141 | canvas.restore();
142 | }
143 |
144 | // 解析时间
145 | private Long parseTime(String time) {
146 | // 03:02.12
147 | String[] min = time.split(":");
148 | String[] sec = min[1].split("\\.");
149 |
150 | long minInt = Long.parseLong(min[0].replaceAll("\\D+", "")
151 | .replaceAll("\r", "").replaceAll("\n", "").trim());
152 | long secInt = Long.parseLong(sec[0].replaceAll("\\D+", "")
153 | .replaceAll("\r", "").replaceAll("\n", "").trim());
154 | long milInt = Long.parseLong(sec[1].replaceAll("\\D+", "")
155 | .replaceAll("\r", "").replaceAll("\n", "").trim());
156 |
157 | return minInt * 60 * 1000 + secInt * 1000 + milInt * 10;
158 | }
159 |
160 | // 解析每行
161 | private String[] parseLine(String line) {
162 | Matcher matcher = Pattern.compile("\\[.+\\].+").matcher(line);
163 | // 如果形如:[xxx]后面啥也没有的,则return空
164 | if (!matcher.matches()) {
165 | System.out.println("throws " + line);
166 | return null;
167 | }
168 |
169 | line = line.replaceAll("\\[", "");
170 | String[] result = line.split("\\]");
171 | result[0] = String.valueOf(parseTime(result[0]));
172 |
173 | return result;
174 | }
175 |
176 | // 外部提供方法
177 | // 传入当前播放时间
178 | public synchronized void changeCurrent(long time) {
179 | // 如果当前时间小于下一句开始的时间
180 | // 直接return
181 | if (mNextTime > time) {
182 | return;
183 | }
184 |
185 | // 每次进来都遍历存放的时间
186 | for (int i = 0; i < mTimes.size(); i++) {
187 | // 发现这个时间大于传进来的时间
188 | // 那么现在就应该显示这个时间前面的对应的那一行
189 | // 每次都重新显示,是不是要判断:现在正在显示就不刷新了
190 | if (mTimes.get(i) > time && i >= mCurrentLine + 1) {
191 | System.out.println("换");
192 | mNextTime = mTimes.get(i);
193 | mCurrentLine = i <= 1 ? 0 : i - 1;
194 | postInvalidate();
195 | break;
196 | }
197 | }
198 | }
199 |
200 | // 外部提供方法
201 | // 设置lrc的路径
202 | public void setLrcPath(String path) throws Exception {
203 | mLrcs.clear();
204 | File file = new File(path);
205 | if (!file.exists()) {
206 | throw new Exception("lrc not found...");
207 | }
208 |
209 | BufferedReader reader = new BufferedReader(new InputStreamReader(
210 | new FileInputStream(file)));
211 |
212 | String line = "";
213 | String[] arr;
214 | while (null != (line = reader.readLine())) {
215 | arr = parseLine(line);
216 | if (null == arr) {
217 | continue;
218 | }
219 |
220 | // 如果解析出来只有一个
221 | if (1 == arr.length) {
222 | String last = mLrcs.remove(mLrcs.size() - 1);
223 | mLrcs.add(last + arr[0]);
224 | continue;
225 | }
226 | mTimes.add(Long.parseLong(arr[0]));
227 | mLrcs.add(arr[1]);
228 | }
229 |
230 | reader.close();
231 | }
232 |
233 | // 外部提供方法
234 | // 设置背景图片
235 | public void setBackground(Bitmap bmp) {
236 | mBackground = bmp;
237 | }
238 | }
239 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | OpenLRC
2 | =======
3 | ##注意:新版本的控件支持歌词的滑动
4 | ## [可以到这里下载](https://github.com/qibin0506/LitePlayer)
5 |
6 | 一个可以在android下显示歌词的控件
7 | 可以设置歌词字体大小,当前行歌词的颜色、其他行歌词的颜色、行间距等。
8 |
9 |
10 | 
11 |
12 |
13 | 使用方法:
14 |
15 | 1、xml布局:
16 |
24 |
25 |
36 |
37 |
38 |
39 | 2、在activity中使用:
40 |
41 | public class MainActivity extends Activity {
42 | private LrcView mLrc;
43 | private MediaPlayer mPlayer;
44 | private String mDir = Environment.getExternalStorageDirectory() + File.separator + "Download" + File.separator;
45 |
46 | @Override
47 | protected void onCreate(Bundle savedInstanceState) {
48 | super.onCreate(savedInstanceState);
49 | setContentView(R.layout.activity_main);
50 |
51 | // 歌曲路径
52 | String music = mDir + "1.mp3";
53 | // 歌词路径
54 | String lrc = mDir + "1.lrc";
55 |
56 | mLrc = (LrcView) findViewById(R.id.lrc);
57 | // 设置背景图片
58 | // 可以选择不设置
59 | // 最好是在真个屏幕设置该图片
60 | // 那样更好看
61 | mLrc.setBackground(BitmapFactory.decodeFile(mDir + "1.png"));
62 |
63 | mPlayer = new MediaPlayer();
64 | try {
65 | mPlayer.setDataSource(music);
66 | mPlayer.setOnPreparedListener(new PreparedListener());
67 | mPlayer.prepareAsync();
68 |
69 | // 设置lrc的路径
70 | mLrc.setLrcPath(lrc);
71 | } catch (Exception e) {
72 | e.printStackTrace();
73 | }
74 | }
75 |
76 | private class PreparedListener implements OnPreparedListener {
77 | @Override
78 | public void onPrepared(MediaPlayer mp) {
79 |
80 | mPlayer.start();
81 | new Thread(new Runnable() {
82 | @Override
83 | public void run() {
84 | // 当歌曲还在播放时
85 | // 就一直调用changeCurrent方法
86 | // 虽然一直调用, 但界面不会一直刷新
87 | // 只有当唱到下一句时才刷新
88 | while(mPlayer.isPlaying()) {
89 | // 调用changeCurrent方法, 参数是当前播放的位置
90 | // LrcView会自动判断需不需要下一行
91 | mLrc.changeCurrent(mPlayer.getCurrentPosition());
92 |
93 | // 当然这里还是要睡一会的啦
94 | try {
95 | Thread.sleep(100);
96 | } catch (InterruptedException e) {
97 | e.printStackTrace();
98 | }
99 | }
100 | }
101 | }).start();
102 | }
103 | }
104 | }
105 |
106 |
--------------------------------------------------------------------------------
/show/show.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qibin0506/OpenLRC/dbcb18c002a0f356aa25184ebcd9ba5e583aac2f/show/show.png
--------------------------------------------------------------------------------