1. 程式人生 > >我的Android進階之旅------>Android自定義View來實現解析lrc歌詞並同步滾動、上下拖動、縮放歌詞的功能

我的Android進階之旅------>Android自定義View來實現解析lrc歌詞並同步滾動、上下拖動、縮放歌詞的功能

這裡寫圖片描述

前言

最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能:
1、實現歌詞同步滾動的功能,即歌曲播放到哪句歌詞,就高亮地顯示出正在播放的這個歌詞;
2、實現上下拖動歌詞時候,可以拖動播放器的進度。即可以不停地上下拖動歌詞,當手指離開螢幕時候 即從當前拖動到的歌詞位置播放。
3、實現歌詞的字型大小可以進行縮放的功能。即雙指在螢幕進行縮放操作時,歌詞的字型大小也進行相應的縮放操作。

下面我將這幾個功能做成一個demo來展示給大家。首先來看看這個demo的具體實現效果,如下面幾幅圖所示。

圖1、同步滾動歌詞
同步滾動歌詞

圖2、上下拖動歌詞1
上下拖動歌詞1

圖3、上下拖動歌詞2
上下拖動歌詞2

圖4、縮放歌詞
縮放歌詞

圖5、歌詞顯示(較大字型)
歌詞顯示(較大字型)

圖6、歌詞顯示(較小字型)
歌詞顯示(較小字型)

圖7、歌詞滾動時候,高亮地畫出正滾動到的歌詞內容以及歌詞的開始時間,並該句歌詞下面畫出一條直線
歌詞滾動截圖

一、LRC歌詞檔案簡介

1、什麼是LRC歌詞檔案

lrc是英文lyric(歌詞)的縮寫,被用做歌詞檔案的副檔名。以lrc為副檔名的歌詞檔案可以在各類數碼播放器中同步顯示。

2、LRC歌詞檔案的格式

先來看一份標準的LRC歌詞檔案,下面展示的是王力巨集的《依然愛你》的lrc歌詞的內容

    [ti:依然愛你]
    [ar:王力巨集]
    [al:火力全開 新歌+精選]
[by:歐陽鵬] [00:01.17]一閃一閃亮晶晶 留下歲月的痕跡 [00:07.29]我的世界的重心 依然還是你 [00:13.37]一年一年又一年 飛逝盡在一轉眼 [00:20.29]唯一永遠不改變 是不停的改變 [00:27.14]我不像從前的自己 你也有點不像你 [00:33.36]但在我眼中你的笑 依然的美麗 [00:39.53]這次只能往前走 一個方向順時鐘 [00:46.12]不知道還要多久 所以要讓你懂 [00:51.82]我依然愛你 就是唯一的退路 [00:57.36]我依然珍惜 時時刻刻的幸福 [01:04.65]你每個呼吸 每個動作 每個表情 [01:11.43]
到最後一定會依然愛你 [01:18.08]依然愛你 依然愛你 [01:25.58]我不像從前的自己 你也有點不像你 [01:31.52]但在我眼中你的笑 依然的美麗 [01:37.61]這次只能往前走 一個方向順時鐘 [01:44.42]不知道還要多久 所以要讓你懂 [01:50.18]我依然愛你 就是唯一的退路 [01:55.65]我依然珍惜 時時刻刻的幸福 [02:02.84]你每個呼吸 每個動作 每個表情 [02:09.77]到最後一定會依然愛你 [02:15.61] [02:17.61]lrc製作:http://blog.csdn.net/ouyang_peng 歐陽鵬 [02:25.61] [02:31.06]依然愛你 依然愛你 [02:36.63] [02:42.32]我依然愛你 或許是命中註定 [02:47.70]多年之後 任何人都無法代替 [02:54.57]那些時光 是我這一輩子 最美好 [03:01.84]那些回憶 依然無法忘記 [03:07.88]我依然愛你 就是唯一的退路 [03:13.95]我依然珍惜 時時刻刻的幸福 [03:21.32]你每個呼吸 每個動作 每個表情 [03:28.20]到最後一定會依然愛你 [03:34.76]你每個呼吸 每個動作 每個表情 [03:42.04]到永遠一定會依然愛你 [03:53.28] [04:01.28]

LRC歌詞檔案的標籤型別

lrc歌詞文字中含有兩類標籤:一是標識標籤 ,二是時間標籤

1、標識標籤

標識標籤,其格式為“[標識名:值]”,主要包含以下預定義的標籤:

  • [ar:歌手名]
  • [ti:歌曲名]
  • [al:專輯名]
  • [by:編輯者(指lrc歌詞的製作人)]
  • [offset:時間補償值] (其單位是毫秒,正值表示整體提前,負值相反。這是用於總體調整顯示快慢的,但多數的MP3可能不會支援這種標籤)。

2、時間標籤

時間標籤,形式為“[mm:ss]”或“[mm:ss.ff]”(分鐘數:秒數.毫秒數),數字須為非負整數,

比如”[12:34.50]”是有效的,而”[0x0C:-34.50]”無效。

時間標籤需位於某行歌詞中的句首部分,一行歌詞可以包含多個時間標籤

(比如歌詞中的迭句部分)。當歌曲播放到達某一時間點時,MP3就會尋找對應的時間標籤並顯示標籤後面的歌詞文字,這樣就完成了“歌詞同步”的功能。

例如下面的這首 草蜢的《失戀戰線聯盟》,就是一行歌詞包含了多個時間標籤。


    [ti:失戀戰線聯盟]
    [ar:草蜢]
    [al:]
    [00:00.00]草蜢-失戀戰線聯盟
    [00:08.78]編輯:小婧
    [01:43.33][00:16.27]她總是隻留下電話號碼
    [01:46.97][00:19.81]從不肯讓我送她回家
    [01:50.61][00:23.43]聽說你也曾經愛上過她
    [01:54.15][00:27.07]曾經也同樣無法自拔
    [01:57.78][00:30.72]你說你學不會假裝瀟灑
    [02:01.41][00:34.36]卻叫我別太早放棄她
    [02:05.05][00:37.99]把過去傳說成一段神話
    [02:08.70][00:41.59]然後笑你是一樣的傻
    [02:12.01][00:45.11]我們那麼在乎她
    [02:14.15][00:47.01]卻被她全部抹殺
    [02:15.96][00:48.87]越談她越相信永遠得不到回答
    [02:19.57][00:52.49]到底她怎麼想
    [02:21.35][00:54.28]應該繼續在這麼
    [02:23.37][00:56.36]還是說穿跑了吧
    [02:26.89][00:59.80]找一個承認失戀的方法
    [02:30.48][01:03.41]讓心情好好地放個假
    [02:34.14][01:07.00]當你我不小心又想起她
    [02:45.69][02:42.20][02:37.69][01:10.60]就在記憶裡畫一個叉
    [02:48.69]
    [01:33.58]編輯:小婧

[01:43.33][00:16.27]她總是隻留下電話號碼
上面這行歌詞表示:

[00:16.27] 這個時間點播放 “她總是隻留下電話號碼” 這句歌詞,

[01:43.33] 這個時間點再一個播放 “她總是隻留下電話號碼” 這句歌詞。

其實可以把上面這行歌詞拆分為下面兩句歌詞:

[00:16.27]她總是隻留下電話號碼
[01:43.33]她總是隻留下電話號碼

二、解析LRC歌詞

1、讀取出歌詞檔案

        /**
         * 從assets目錄下讀取歌詞檔案內容
         * @param fileName
         * @return
         */
        public String getFromAssets(String fileName){
            try {
                InputStreamReader inputReader = new InputStreamReader( getResources().getAssets().open(fileName) );
                BufferedReader bufReader = new BufferedReader(inputReader);
                String line="";
                String result="";
                while((line = bufReader.readLine()) != null){
                    if(line.trim().equals(""))
                        continue;
                    result += line + "\r\n";
                }
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }

例如:從assets目錄下讀取test.lrc歌詞檔案內容,則可以呼叫上面的getFromAssets(String fileName)方法得到歌詞的文字內容,如下所示:

    String lrc = getFromAssets("test.lrc");

2、解析得到的歌詞內容

1、表示每行歌詞內容的實體類LrcRow

首先封裝一個表示每行歌詞內容的實體類LrcRow,該類由三個屬性,分別為:
strTime、time、content。

例如一行歌詞內容為:[02:34.14]當你我不小心又想起她 , 解析該行歌詞後的實體類LrcRow的屬性如下所示:

  • strTime表示該行歌詞要開始播放的時間,格式如下:[02:34.14]
  • time表示將strTime轉換為long型之後的數值

    例如將strTime為[02:34.14]格式轉換154014(154014=02 * 60 * 1000 + 34 * 1000+14)

  • content表示該行歌詞的內容,如:當你我不小心又想起她

程式碼如下:

    package com.oyp.lrc.view.impl;

    import android.util.Log;

    import java.util.ArrayList;
    import java.util.List;

    /**
     * 歌詞行
     * 包括該行歌詞的時間,歌詞內容
     */
    public class LrcRow implements Comparable<LrcRow>{
        public final static String TAG = "LrcRow";

        /** 該行歌詞要開始播放的時間,格式如下:[02:34.14] */
        public String strTime;

        /** 該行歌詞要開始播放的時間,由[02:34.14]格式轉換為long型,
         * 即將2分34秒14毫秒都轉為毫秒後 得到的long型值:time=02*60*1000+34*1000+14
         */
        public long time;

        /** 該行歌詞的內容 */
        public String content;


        public LrcRow(){}

        public LrcRow(String strTime,long time,String content){
            this.strTime = strTime;
            this.time = time;
            this.content = content;
    //      Log.d(TAG,"strTime:" + strTime + " time:" + time + " content:" + content);
        }

        @Override
        public String toString() {
            return "[" + strTime + " ]"  + content;
        }

        /**
         * 讀取歌詞的每一行內容,轉換為LrcRow,加入到集合中
         */
        public static List<LrcRow> createRows(String standardLrcLine){
            /**
                一行歌詞只有一個時間的  例如:徐佳瑩   《我好想你》
                [01:15.33]我好想你 好想你

                一行歌詞有多個時間的  例如:草蜢 《失戀戰線聯盟》
                [02:34.14][01:07.00]當你我不小心又想起她
                [02:45.69][02:42.20][02:37.69][01:10.60]就在記憶裡畫一個叉
             **/
            try{
                if(standardLrcLine.indexOf("[") != 0 || standardLrcLine.indexOf("]") != 9 ){
                    return null;
                }
                //[02:34.14][01:07.00]當你我不小心又想起她
                //找到最後一個 ‘]’ 的位置
                int lastIndexOfRightBracket = standardLrcLine.lastIndexOf("]");
                //歌詞內容就是 ‘]’ 的位置之後的文字   eg:   當你我不小心又想起她
                String content = standardLrcLine.substring(lastIndexOfRightBracket + 1, standardLrcLine.length());
                //歌詞時間就是 ‘]’ 的位置之前的文字   eg:   [02:34.14][01:07.00]

                /**
                    將時間格式轉換一下  [mm:ss.SS][mm:ss.SS] 轉換為  -mm:ss.SS--mm:ss.SS-
                    即:[02:34.14][01:07.00]  轉換為      -02:34.14--01:07.00-
                 */
                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;
                    }
                    /** [02:34.14][01:07.00]當你我不小心又想起她
                     *
                        上面的歌詞的就可以拆分為下面兩句歌詞了
                        [02:34.14]當你我不小心又想起她
                        [01:07.00]當你我不小心又想起她
                     */
                    LrcRow lrcRow = new LrcRow(temp, timeConvert(temp), content);
                    listTimes.add(lrcRow);
                }
                return listTimes;
            }catch(Exception e){
                Log.e(TAG,"createRows exception:" + e.getMessage());
                return null;
            }
        }

        /**
         * 將解析得到的表示時間的字元轉化為Long型
         */
        private static long timeConvert(String timeString){
            //因為給如的字串的時間格式為XX:XX.XX,返回的long要求是以毫秒為單位
            //將字串 XX:XX.XX 轉換為 XX:XX:XX
            timeString = timeString.replace('.', ':');
            //將字串 XX:XX:XX 拆分
            String[] times = timeString.split(":");
            // mm:ss:SS
            return Integer.valueOf(times[0]) * 60 * 1000 +//分
                    Integer.valueOf(times[1]) * 1000 +//秒
                    Integer.valueOf(times[2]) ;//毫秒
        }

        /**
         * 排序的時候,根據歌詞的時間來排序
         */
        public int compareTo(LrcRow another) {
            return (int)(this.time - another.time);
        }
    }

該LrcRow的List createRows(String standardLrcLine)方法 ,將迴圈地一行一行的去讀取歌詞的內容。然後對每一行的歌詞進行解析,每解析出一個時間標籤[XX:XX.XX]則new出一個LrcRow物件,然後加入到歌詞行List集合中去。

該LrcRow類實現Comparable介面,用來進行解析之後的排序操作,排序按時間從小到大排序。

2、解析歌詞的構造器

ILrcBuilder介面

定義一個ILrcBuilder介面,介面有一個List getLrcRows(String rawLrc)方法,該方法用來解析歌詞,得到LrcRow的集合

    package com.oyp.lrc.view;

    import com.oyp.lrc.view.impl.LrcRow;

    import java.util.List;

    /**
     * 解析歌詞,得到LrcRow的集合
     */
    public interface ILrcBuilder {
        List<LrcRow> getLrcRows(String rawLrc);
    }

DefaultLrcBuilder歌詞解析構造器

DefaultLrcBuilder實現ILrcBuilder介面,List getLrcRows(String rawLrc)方法會迴圈地讀取歌詞的每一行,然後呼叫LrcRow類的List createRows(String standardLrcLine)方法,得到解析每一行歌詞之後的LrcRow集合,再將每一行得到LrcRow集合中得到的LrcRow實體加入一個總 的到LrcRow集合rows中去,然後將rows集合根據歌詞行的時間排序,得到排序後的LrcRow集合,該集合就是最終的解析歌詞後的內容了。

程式碼如下:

    package com.oyp.lrc.view.impl;

    import android.util.Log;
    import com.oyp.lrc.view.ILrcBuilder;
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.StringReader;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;

    /**
     * 解析歌詞,得到LrcRow的集合
     */
    public class DefaultLrcBuilder implements ILrcBuilder {
        static final String TAG = "DefaultLrcBuilder";

        public List<LrcRow> getLrcRows(String rawLrc) {
            Log.d(TAG,"getLrcRows by rawString");
            if(rawLrc == null || rawLrc.length() == 0){
                Log.e(TAG,"getLrcRows rawLrc null or empty");
                return null;
            }
            StringReader reader = new StringReader(rawLrc);
            BufferedReader br = new BufferedReader(reader);
            String line = null;
            List<LrcRow> rows = new ArrayList<LrcRow>();
            try{
                //迴圈地讀取歌詞的每一行
                do{
                    line = br.readLine();
                    /**
                     一行歌詞只有一個時間的  例如:徐佳瑩   《我好想你》
                     [01:15.33]我好想你 好想你

                     一行歌詞有多個時間的  例如:草蜢 《失戀戰線聯盟》
                     [02:34.14][01:07.00]當你我不小心又想起她
                     [02:45.69][02:42.20][02:37.69][01:10.60]就在記憶裡畫一個叉
                     **/
                    Log.d(TAG,"lrc raw line: " + line);
                    if(line != null && line.length() > 0){
                        //解析每一行歌詞 得到每行歌詞的集合,因為有些歌詞重複有多個時間,就可以解析出多個歌詞行來
                        List<LrcRow> lrcRows = LrcRow.createRows(line);
                        if(lrcRows != null && lrcRows.size() > 0){
                            for(LrcRow row : lrcRows){
                                rows.add(row);
                            }
                        }
                    }
                }while(line != null);

                if( rows.size() > 0 ){
                    // 根據歌詞行的時間排序
                    Collections.sort(rows);
                    if(rows!=null&&rows.size()>0){
                        for(LrcRow lrcRow:rows){
                            Log.d(TAG, "lrcRow:" + lrcRow.toString());
                        }
                    }
                }
            }catch(Exception e){
                Log.e(TAG,"parse exceptioned:" + e.getMessage());
                return null;
            }finally{
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                reader.close();
            }
            return rows;
        }
    }

例如:通過下面程式碼來呼叫ILrcBuilder解析歌詞,

        //從assets目錄下讀取歌詞檔案內容
        String lrc = getFromAssets("test.lrc");
        //解析歌詞構造器
        ILrcBuilder builder = new DefaultLrcBuilder();
        //解析歌詞返回LrcRow集合
        List<LrcRow> rows = builder.getLrcRows(lrc);

lrc歌詞原始內容

草蜢的《失戀戰線聯盟》,lrc原始內容如下:

    [ti:失戀戰線聯盟]
    [ar:草蜢]
    [al:]
    [00:00.00]草蜢-失戀戰線聯盟
    [00:08.78]編輯:小婧
    [01:43.33][00:16.27]她總是隻留下電話號碼
    [01:46.97][00:19.81]從不肯讓我送她回家
    [01:50.61][00:23.43]聽說你也曾經愛上過她
    [01:54.15][00:27.07]曾經也同樣無法自拔
    [01:57.78][00:30.72]你說你學不會假裝瀟灑
    [02:01.41][00:34.36]卻叫我別太早放棄她
    [02:05.05][00:37.99]把過去傳說成一段神話
    [02:08.70][00:41.59]然後笑你是一樣的傻
    [02:12.01][00:45.11]我們那麼在乎她
    [02:14.15][00:47.01]卻被她全部抹殺
    [02:15.96][00:48.87]越談她越相信永遠得不到回答
    [02:19.57][00:52.49]到底她怎麼想
    [02:21.35][00:54.28]應該繼續在這麼
    [02:23.37][00:56.36]還是說穿跑了吧
    [02:26.89][00:59.80]找一個承認失戀的方法
    [02:30.48][01:03.41]讓心情好好地放個假
    [02:34.14][01:07.00]當你我不小心又想起她
    [02:45.69][02:42.20][02:37.69][01:10.60]就在記憶裡畫一個叉
    [02:48.69]
    [01:33.58]編輯:小婧

讀取該歌詞內容,過程中的列印日誌為:

    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [ti:失戀戰線聯盟]
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [ar:草蜢]
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [al:]
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [00:00.00]草蜢-失戀戰線聯盟
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [00:08.78]編輯:小婧
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:43.33][00:16.27]她總是隻留下電話號碼
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:46.97][00:19.81]從不肯讓我送她回家
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:50.61][00:23.43]聽說你也曾經愛上過她
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:54.15][00:27.07]曾經也同樣無法自拔
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:57.78][00:30.72]你說你學不會假裝瀟灑
    03-06 00:41:15.352 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:01.41][00:34.36]卻叫我別太早放棄她
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:05.05][00:37.99]把過去傳說成一段神話
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:08.70][00:41.59]然後笑你是一樣的傻
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:12.01][00:45.11]我們那麼在乎她
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:14.15][00:47.01]卻被她全部抹殺
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:15.96][00:48.87]越談她越相信永遠得不到回答
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:19.57][00:52.49]到底她怎麼想
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:21.35][00:54.28]應該繼續在這麼
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:23.37][00:56.36]還是說穿跑了吧
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:26.89][00:59.80]找一個承認失戀的方法
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:30.48][01:03.41]讓心情好好地放個假
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:34.14][01:07.00]當你我不小心又想起她
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:45.69][02:42.20][02:37.69][01:10.60]就在記憶裡畫一個叉
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [02:48.69]
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: [01:33.58]編輯:小婧
    03-06 00:41:15.362 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrc raw line: null

解析歌詞後遍歷List<LrcRow>集合的列印日誌為:

    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:00.00 ]草蜢-失戀戰線聯盟
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:08.78 ]編輯:小婧
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:16.27 ]她總是隻留下電話號碼
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:19.81 ]從不肯讓我送她回家
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:23.43 ]聽說你也曾經愛上過她
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:27.07 ]曾經也同樣無法自拔
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:30.72 ]你說你學不會假裝瀟灑
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:34.36 ]卻叫我別太早放棄她
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:37.99 ]把過去傳說成一段神話
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:41.59 ]然後笑你是一樣的傻
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:45.11 ]我們那麼在乎她
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:47.01 ]卻被她全部抹殺
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:48.87 ]越談她越相信永遠得不到回答
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:52.49 ]到底她怎麼想
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:54.28 ]應該繼續在這麼
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:56.36 ]還是說穿跑了吧
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[00:59.80 ]找一個承認失戀的方法
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:03.41 ]讓心情好好地放個假
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:07.00 ]當你我不小心又想起她
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:10.60 ]就在記憶裡畫一個叉
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:33.58 ]編輯:小婧
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:43.33 ]她總是隻留下電話號碼
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:46.97 ]從不肯讓我送她回家
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:50.61 ]聽說你也曾經愛上過她
    03-06 00:41:15.372 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:54.15 ]曾經也同樣無法自拔
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[01:57.78 ]你說你學不會假裝瀟灑
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:01.41 ]卻叫我別太早放棄她
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:05.05 ]把過去傳說成一段神話
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:08.70 ]然後笑你是一樣的傻
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:12.01 ]我們那麼在乎她
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:14.15 ]卻被她全部抹殺
    03-06 00:41:15.382 5265-5265/com.oyp.lrc D/DefaultLrcBuilder: lrcRow:[02:15.96 ]越談她越相信永遠得不到回答
    
            
           

相關推薦

Android定義ContentProvider

引言 我們知道Android有四大元件,ContentProvider是其中之一,顧名思義:內容提供者。什麼是內容提供者呢?一個抽象類,可以暴露應用的資料給其他應用。應用裡的資料通常說的是資料庫,事實上普通的檔案,甚至是記憶體中的物件,也可以作為內容提供者暴露的

Android定義控制元件使用ViewPager實現可以預覽的畫廊效果,並且定義畫面切換的動畫效果的切換時間

我們來看下效果 在這裡,我們實現的是,一個ViewPager來顯示圖片列表。這裡一個頁面,ViewPage展示了前後的預覽,我們讓預覽頁進行Y軸的壓縮,並設定透明度為0.5f,所有我們看到gif最後,左右兩邊的圖片有點朦朧感。讓預覽頁和主頁面有主從感。我們用分

Android------>Android定義View實現解析lrc歌詞同步滾動上下歌詞功能

前言 最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能: 1、實現歌詞同步滾動的功能,即歌曲播放到哪句歌詞,就高亮地顯示出正在播放的這個歌詞; 2、實現上下拖動歌詞時候,可以拖動播放器的進度。即可以不停地上下拖動歌詞,

Android定義View實現解析lrc歌詞同步滾動上下歌詞功能

http://blog.csdn.net/ouyang_peng/article/details/50813419 前言 最近有個專案有關於播放音樂時候,關於歌詞有以下幾個功能:  1、實現歌詞同步滾動的功能,即歌曲播放到哪句

Android------>Android如何通過定義SeekBar實現視訊播放進度條

首先來看一下效果圖,如下所示:其中進度條如下:接下來說一說我的思路,上面的進度拖動條有自定義的Thumb,在Thumb正上方有一個PopupWindow視窗,窗口裡面顯示當前的播放時間。在SeekBar右邊有一個文字框顯示當前播放時間/總時間。step1、先來看一看Popup

Android------>Android定義View實現帶數字的進度條(NumberProgressBar)

今天在Github上面看到一個來自於 daimajia所寫的關於Android自定義View實現帶數字的進度條(NumberProgressBar)的精彩案例,在這裡分享給大家一起來學習學習!同時感謝daimajia的開源奉獻! 第一步、效果展

Android------>android中一些特殊字元(如:←↑→↓等箭頭符號)的Unicode碼值

        在專案中,有時候在一些控制元件(如Button、TextView)中要新增一些符號,如下圖所示:                        這個時候可以使用圖片的方式來顯示,不過這些

Android------>Android 關於arm64-v8aarmeabi-v7aarmeabix86下的so檔案相容問題

Android 裝置的CPU型別(通常稱為”ABIs”) armeabiv-v7a: 第7代及以上的 ARM 處理器。2011年15月以後的生產的大部分Android裝置都使用它. arm64-v8a: 第8代、64位ARM處理器,很少裝置,三星 Ga

Android------>Android中高低API版本相容使用@TargetApi或者@SuppressLint("NewApi")

Android中高低API版本相容使用@TargetApi或者@SuppressLint("NewApi") 例如:AndroidManifest.xml中,我們配置了sdk版本的最低為9,目標sdk

Android------>Android顏色值(#AARRGGBB)透明度百分比和十六位制對應關係以及計算方法

透明度百分比和十六進位制對應關係表格 透明度 十六進位制 100% FF 99% FC 98% FA 97% F7 96%

Android------>android視訊播放只有聲音無畫面的解決辦法

            今天除錯公司用VideoView實現的播放器來播放視訊的時候,只有聲音輸出而無畫面輸出。一開始以為是自己程式有問題,除錯了半天無果。懷疑是真機本身的問題,於是下了幾個第三方的

Android------>android Matrix圖片隨意的放大縮小,

step1:新建一個專案DragAndZoom,並準備一張照片放在res/drawable-hdpi目錄下,如下圖所示:         step2: 設定應用的UI介面,在main.xml中設定: <?xmlversion="1.0"encoding="u

Android------>Android採用AES+RSA的加密機制對http請求進行加密

本文轉載自部落格:http://blog.csdn.net/ouyang_peng/article/details/50983574 ----------------------------------------------------------------------

Android------>Android中可替換string的使用,getString(int resId, Object... formatArgs)

官方文件如下描述: public finalStringgetString (int resId,Object... formatArgs) Return a localized formatte

[置頂] Android------>Android解決異常: startRecording() called on an uninitialized AudioRecord.

今天使用AudioRecord進行錄音操作時候,報了下面的異常。E/AndroidRuntime(22775): java.lang.IllegalStateException: startRecord

Android------>Android使用百度地圖時,關於android.permission.BAIDU_LOCATION_SERVICE的宣告警告。

【重要提醒】 定位SDKv3.1版本之後,以下許可權已不需要,請取消宣告,否則將由於Android 5.0多帳戶系統加強許可權管理而導致應用安裝失敗。 <uses-permission and

Android------>Android實現音樂示波器均衡器重低音和音場功能

package com.oyp.media; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.content.Context; import android.gra

android-(3)-定義view(2)-AndroidView繪製流程以及相關方法的分析

最近正在學自定義view,這篇文章主要講view的繪製流程和一些相關的方法,淺顯易懂,寫的非常好,忍不住就轉載了。             前言: 本文是我讀《Android核心剖析》第13章----View工作原理總結而成的,在此膜拜下作者 。

android-(3)-定義view(1)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"     xmlns:custom="http://sch

Android】關於解析json資料中帶轉義符號的正確操作

一、問題描述 在實現一個功能的時候,需要伺服器以json格式返回一段功能配置,比如如下所示的json配置。 1.1 我希望的json格式 { "k": "ClientFilterTrace_android", "isVisible": true