Android 音樂播放器實現歌詞顯示
阿新 • • 發佈:2019-02-17
LrcHandle.java:
WordView.java:package com.example.welcome; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; /*** * 獲取時間以及對應的歌詞 * * @author chao * */ public class LrcHandle { private List<String> mWords = new ArrayList<String>(); private List<Integer> mTimeList = new ArrayList<Integer>(); // 處理歌詞檔案 public void readLRC(String path) { File file = new File(path); try { FileInputStream fileInputStream = new FileInputStream(file); InputStreamReader inputStreamReader = new InputStreamReader( fileInputStream, "GBK"); BufferedReader bufferedReader = new BufferedReader( inputStreamReader); String s = ""; while ((s = bufferedReader.readLine()) != null) { addTimeToList(s); if ((s.indexOf("[ar:") != -1) || (s.indexOf("[ti:") != -1) || (s.indexOf("[by:") != -1)) { s = s.substring(s.indexOf(":") + 1, s.indexOf("]")); } else { // ss為時間 [02:12.22] String ss = s.substring(s.indexOf("["), s.indexOf("]") + 1); // s為ss時間後的歌詞 s = s.replace(ss, ""); } mWords.add(s); } bufferedReader.close(); inputStreamReader.close(); fileInputStream.close(); } catch (FileNotFoundException e) { e.printStackTrace(); mWords.add("沒有歌詞檔案,趕緊去下載"); } catch (IOException e) { e.printStackTrace(); mWords.add("沒有讀取到歌詞"); } } public List<String> getWords() { return mWords; } public List<Integer> getTime() { return mTimeList; } // 分離出時間 private int timeHandler(String string) { string = string.replace(".", ":"); String timeData[] = string.split(":"); // 分離出分、秒並轉換為整型 int minute = Integer.parseInt(timeData[0]); int second = Integer.parseInt(timeData[1]); int millisecond = Integer.parseInt(timeData[2]); // 計算上一行與下一行的時間轉換為毫秒數 int currentTime = (minute * 60 + second) * 1000 + millisecond * 10; return currentTime; } private void addTimeToList(String string) { Matcher matcher = Pattern.compile( "\\[\\d{1,2}:\\d{1,2}([\\.:]\\d{1,2})?\\]").matcher(string); if (matcher.find()) { String str = matcher.group(); mTimeList.add(new LrcHandle().timeHandler(str.substring(1, str.length() - 1))); } } }
MainActivity.java:package com.example.welcome; import java.io.IOException; import java.util.ArrayList; import java.util.List; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.TextView; public class WordView extends TextView { private List mWordsList = new ArrayList(); private Paint mLoseFocusPaint; private Paint mOnFocusePaint; private float mX = 0; private float mMiddleY = 0; private float mY = 0; private static final int DY = 50; private int mIndex = 0; public WordView(Context context) throws IOException { super(context); init(); } public WordView(Context context, AttributeSet attrs) throws IOException { super(context, attrs); init(); } public WordView(Context context, AttributeSet attrs, int defStyle) throws IOException { super(context, attrs, defStyle); init(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.BLACK); Paint p = mLoseFocusPaint; p.setTextAlign(Paint.Align.CENTER); Paint p2 = mOnFocusePaint; p2.setTextAlign(Paint.Align.CENTER); canvas.drawText((String) mWordsList.get(mIndex), mX, mMiddleY, p2); int alphaValue = 25; float tempY = mMiddleY; for (int i = mIndex - 1; i >= 0; i--) { tempY -= DY; if (tempY < 0) { break; } p.setColor(Color.argb(255 - alphaValue, 245, 245, 245)); canvas.drawText((String) mWordsList.get(i), mX, tempY, p); alphaValue += 25; } alphaValue = 25; tempY = mMiddleY; for (int i = mIndex + 1, len = mWordsList.size(); i < len; i++) { tempY += DY; if (tempY > mY) { break; } p.setColor(Color.argb(255 - alphaValue, 245, 245, 245)); canvas.drawText((String) mWordsList.get(i), mX, tempY, p); alphaValue += 25; } mIndex++; } @Override protected void onSizeChanged(int w, int h, int ow, int oh) { super.onSizeChanged(w, h, ow, oh); mX = w * 0.5f; mY = h; mMiddleY = h * 0.3f; } @SuppressLint("SdCardPath") private void init() throws IOException { setFocusable(true); LrcHandle lrcHandler = new LrcHandle(); lrcHandler.readLRC("/sdcard/aa.lrc"); mWordsList = lrcHandler.getWords(); mLoseFocusPaint = new Paint(); mLoseFocusPaint.setAntiAlias(true); mLoseFocusPaint.setTextSize(22); mLoseFocusPaint.setColor(Color.WHITE); mLoseFocusPaint.setTypeface(Typeface.MONOSPACE); mOnFocusePaint = new Paint(); mOnFocusePaint.setAntiAlias(true); mOnFocusePaint.setColor(Color.YELLOW); mOnFocusePaint.setTextSize(40); mOnFocusePaint.setTypeface(Typeface.SANS_SERIF); } }
main.xml:package com.example.welcome; import java.io.IOException; import java.util.List; import android.R.integer; import android.annotation.SuppressLint; import android.app.Activity; import android.media.MediaPlayer; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { private WordView mWordView; private List mTimeList; private MediaPlayer mPlayer; @SuppressLint("SdCardPath") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { mPlayer.stop(); finish(); } }); mWordView = (WordView) findViewById(R.id.text); mPlayer = new MediaPlayer(); mPlayer.reset(); LrcHandle lrcHandler = new LrcHandle(); try { lrcHandler.readLRC("/sdcard/aa.lrc"); mTimeList = lrcHandler.getTime(); mPlayer.setDataSource("/sdcard/e.mp3"); mPlayer.prepare(); } catch (IOException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalStateException e) { e.printStackTrace(); } final Handler handler = new Handler(); mPlayer.start(); new Thread(new Runnable() { int i = 0; @Override public void run() { while (mPlayer.isPlaying()) { handler.post(new Runnable() { @Override public void run() { mWordView.invalidate(); } }); try { Thread.sleep(Integer.parseInt(mTimeList.get(i + 1) .toString()) - Integer.parseInt(mTimeList.get(i).toString())); } catch (InterruptedException e) { } i++; if (i == mTimeList.size() - 1) { mPlayer.stop(); break; } } } }).start(); } }
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<Button
android:id="@+id/button"
android:layout_width="60dip"
android:layout_height="60dip"
android:text="stop" />
<com.example.welcome.WordView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/button"
android:text="song" />
</RelativeLayout>