1. 程式人生 > >Android漂亮的音樂歌詞控制元件,仿網易雲音樂滑動效果

Android漂亮的音樂歌詞控制元件,仿網易雲音樂滑動效果

前言: 專案有個音樂播發器功能,實現音樂線上播放,同時需要帶有歌詞顯示功能。網上也找過,在github找到勉強能用的控制元件,只是效果還是差強人意,不是特別好。於是趁有空的時間,參考了網上的部分demo,自己也寫了個歌詞控制元件。

只要demo可以拉到最底部。

一.歌詞控制元件效果。

目前的歌詞控制元件效果如下:

歌詞自動滑動效果

歌詞進度跳轉效果

歌詞手勢滑動效果
主要效果有以下:

1.實現自動滑動切換到下一句。
2.實現滑動歌詞切換播放時間。
3.實現拖動歌詞時仿網易雲音樂顯示時間線,將要選擇的歌詞顏色變化。
4.音樂進度跳轉時,歌詞跳轉可以滑動切換。

二.歌詞控制元件實現邏輯說明

1.歌詞解析。


歌詞檔案問lrc檔案,歌詞內容格式都是固定的[01:15.33] 或者 [00:00]這種格式。所以先把歌詞內容通過一行一行的讀取,每讀取一行就解析。

List<LrcRow> rows = new ArrayList<LrcRow>();

            // 迴圈地讀取歌詞的每一行
            do {
                line = br.readLine();

                if (line != null && line.length() > 0) {
                    // 解析每一行歌詞 得到每行歌詞的集合,因為有些歌詞重複有多個時間,就可以解析出多個歌詞行來
List<LrcRow> lrcRows = createRows(line);//解析行資料 if (lrcRows != null && lrcRows.size() > 0) { for (LrcRow row : lrcRows) { rows.add(row); } } } } while
(line != null);
    private List<LrcRow> createRows(String standardLrcLine) {

        try {
            // [01:15.33] 或者 [00:00]這種格式
            Boolean Form1 = standardLrcLine.indexOf("[") == 0 && standardLrcLine.indexOf("]") == 9;
            Boolean Form2 = standardLrcLine.indexOf("[") == 0 && standardLrcLine.indexOf("]") == 6;

            if (!Form1 && !Form2) {
                return null;
            }

            int lastIndexOfRightBracket = standardLrcLine.lastIndexOf("]");

            String content = standardLrcLine.substring(lastIndexOfRightBracket + 1, standardLrcLine.length());      

            String times = standardLrcLine.substring(0, lastIndexOfRightBracket + 1).replace("[", "-").replace("]",
                    "-");

            String arrTimes[] = times.split("-");
            List<LrcRow> listTimes = new ArrayList<LrcRow>();
            for (String temp : arrTimes) {
                if (temp.trim().length() == 0) {
                    continue;
                }

                LrcRow lrcRow = new LrcRow(content, temp, timeConvert(temp));
                listTimes.add(lrcRow);
            }
            return listTimes;
        } catch (Exception e) {         
            return null;
        }
    }

LrcRow是實現Comparable的類,儲存了沒行歌詞的資料,包括歌詞內容、時間,實現Comparable可以通過時間來進行歌詞排序。

public class LrcRow implements Comparable<LrcRow>{

    private String RowData;//行資料
    private List<LrcShowRow> ShowRows = new ArrayList<LrcShowRow>();//顯示的行
    public String TimeText;
    public long CurrentRowTime;

LrcShowRow是繪製顯示的行資料,因為讀取的沒行資料,如果長度過長就可能要通過多行才能顯示完,這時需要擷取為多行顯示。

public class LrcShowRow implements Comparable<LrcShowRow> {

    public String Data;// 行資料
    public float RowHeight;// 行高度
    public float RowPadding;// 行間距
    public float YPosition =0;//繪畫y位置
    public int Index;//所在行座標

2.歌詞繪製

a.如果在手勢滑動狀態,繪製時間線

b.從第一行資料開始繪製,從頭到位將所有行資料繪製一遍。注意的是,第一行開始繪製座標FirstRowPositionY是動態控制,目的是方便手勢滑動或者執行動畫時改變這個座標就能實現控制元件滑動效果。繪製過程中需要記錄每一行繪製的Y位置,這個座標的作用是為了執行動畫時計算需要的滑動距離。如果當前行是選中行或者如果當前行是手勢滑動時想要選擇的行,改變為對應的顯示顏色。

c.音樂播放時間跳轉時,查詢到歌詞中與跳轉時間最匹配的歌詞,拿到將要選中位置下標TrySelectionPosition,然後執行動畫,執行動畫時先計算出總共偏移量然後一點點改變FirstRowPositionY偏移位置實現滑動效果。動畫執行完成,將選中下標更改為TrySelectionPosition。

三.下載地址,歡迎issue