一篇讀懂(安卓仿網(wǎng)易云音樂源碼)仿網(wǎng)易云音樂的android源碼,Android項(xiàng)目實(shí)戰(zhàn)之高仿網(wǎng)易云音樂LRC歌詞,他們那時(shí)候多有趣,
目錄:
1.仿網(wǎng)易云音樂app源碼
2.安卓開發(fā)仿網(wǎng)易云
3.仿網(wǎng)易云音樂網(wǎng)站源碼
4.仿網(wǎng)易云音樂播放器
5.仿網(wǎng)易云音樂小程序
6.仿網(wǎng)易云音樂html模板
7.仿網(wǎng)易云音樂網(wǎng)頁版
8.html仿網(wǎng)易云網(wǎng)站
9.仿網(wǎng)易云音樂源碼html5
10.仿網(wǎng)易云音樂小程序源碼
1.仿網(wǎng)易云音樂app源碼
Linux編程點(diǎn)擊右側(cè)關(guān)注,免費(fèi)入門到精通!
2.安卓開發(fā)仿網(wǎng)易云
作者丨愛學(xué)啊https://www.jianshu.com/p/c1d8bd6d7178
3.仿網(wǎng)易云音樂網(wǎng)站源碼
效果圖相信大家都懂一張圖勝過千言萬語。
4.仿網(wǎng)易云音樂播放器
效果和現(xiàn)在市面上大部分播放器差不多,當(dāng)然如果要運(yùn)用到商業(yè)項(xiàng)目中,肯定還需要進(jìn)行一些優(yōu)化合肥市最低工資標(biāo)準(zhǔn)2019,例如:滾動效果有彈性,字體大小,字體顏色等。
5.仿網(wǎng)易云音樂小程序
什么是LRC歌詞LRC是英文Lyric(歌詞)的縮寫,常用作逐行歌詞擴(kuò)展名他是純文本文件,格式簡單,能實(shí)現(xiàn)歌詞逐行滾動;當(dāng)然目前業(yè)界大部分播放器都是在他的基礎(chǔ)上定制了,但基本原理一樣,當(dāng)學(xué)完我們這篇文章后,大家也可以根據(jù)自己的需求定制。
6.仿網(wǎng)易云音樂html模板
LRC歌詞格式在實(shí)現(xiàn)歌詞功能前,肯定需要搞明白LRC歌詞格式,例如:我們找了一段LRC歌詞:[ti:愛的代價(jià)][ar:李宗盛][al:滾石香港黃金十年 李宗盛精選][ly:李宗盛][mu:李宗盛][ma:
7.仿網(wǎng)易云音樂網(wǎng)頁版
][pu:][by:ttpod][tota合肥市最低工資標(biāo)準(zhǔn)2019l:272073][offset:0][00:00.300]愛的代價(jià) - 李宗盛[00:01.979]作詞:李宗盛[00:03.312]作曲:李宗盛[00:06.429
8.html仿網(wǎng)易云網(wǎng)站
][00:16.282]還記得年少時(shí)的夢嗎[00:20.575]像朵永遠(yuǎn)不調(diào)零的花[00:24.115]陪我經(jīng)過那風(fēng)吹雨打[00:27.921]看世事無常[00:29.653]看滄桑變化[00:32.576
9.仿網(wǎng)易云音樂源碼html5
]那些為愛所付出的代價(jià)[00:36.279]是永遠(yuǎn)都難忘的啊[00:40.485]所有真心的癡心的話可以看到內(nèi)容是用換行符分割的,如果這些數(shù)據(jù)是通過接口返回,而不是直接返回合肥市最低工資標(biāo)準(zhǔn)2019一個(gè)LRC文件,那么這里面的換行符應(yīng)該變?yōu)閈n換行符,這一點(diǎn)我們也在課程中講解到了。
10.仿網(wǎng)易云音樂小程序源碼
每一行是一句歌詞;每一行歌詞又分為兩部分,中括號里面是當(dāng)前這行歌詞的開始時(shí)間,格式為分:秒:毫秒,有些歌詞可能沒有毫秒,只有秒;歌詞開頭由于部分?jǐn)?shù)據(jù)稱為LRC元數(shù)據(jù),他是用來描述這個(gè)歌詞的,部分字段解釋如下:
ti:title,標(biāo)題,通常是歌曲名稱ar:artist,藝人名al:album,專輯名by:歌詞創(chuàng)建人,這里是ttpod,指的是天天動聽total:整首歌曲時(shí)長,單位毫秒offset:時(shí)間補(bǔ)償值,單位毫秒,正值表示整體提前,負(fù)值相反
前面這些字段根據(jù)不同的播放器可能用的位置不一樣合肥市最低工資標(biāo)準(zhǔn)2019,我們課程中雖然解析了這些字段,但也沒有用到。
歌詞滾動原理將每行歌詞前面的時(shí)間解析后,轉(zhuǎn)為毫秒,這樣播放器在播放的時(shí)候可以獲取到播放時(shí)間,然后拿著時(shí)間查找當(dāng)前時(shí)間對應(yīng)哪一行歌詞,然后在界面上高亮這一行歌詞,或者做更多的處理,例如:字體增大等操作;就實(shí)現(xiàn)了歌詞逐行高亮;至于滾動不同的平臺不一樣,滾動思路是:獲取到當(dāng)前時(shí)間所對應(yīng)哪一行,然后我們肯定能算出每一行歌詞高度,所以行*每一行高度就是滾動的高度。
歌詞解析不同的語言語法不一樣,我們這里先說思路,我們的實(shí)現(xiàn)是Java語言讀取該文件每一行,然后用]拆分,第二部分就是歌詞,第一部分繼續(xù)用:拆分,然后將三部分轉(zhuǎn)為毫秒;最后將這些信息保存到對象上當(dāng)然為合肥市最低工資標(biāo)準(zhǔn)2019了以后更好的擴(kuò)展,因?yàn)楦柙~格式很多,可以進(jìn)行一些架構(gòu):。
String[] strings = content.split("\n");lyric = new Lyric();TreeMap lyrics = new TreeMap<>();
Map tags = new HashMap<>();String lineInfo=null;int lineNumber = 0;for (int i = 0; i < strings.length; i++) {
try { lineInfo=strings[i]; Line line = parserLine(tags, l合肥市最低工資標(biāo)準(zhǔn)2019ineInfo);if (line != null) { lyrics.put(lineNumber, line);
lineNumber++; } } catch (Exception var9) { var9.printStackTrace(); }}
lyric.setLyrics(lyrics);lyric.setTags(tags);/** * 解析每一行歌詞 */private Line parserLine(Map
> tags, String lineInfo) {if (lineInfo.startsWith("[0")合肥市最低工資標(biāo)準(zhǔn)2019) {//歌詞開始了 Line line = new Line();int leftIndex =
1;int rightIndex = lineInfo.length();String[] lineComments = lineInfo.substring(leftIndex, rightIndex).split(
"]", -1);//開始時(shí)間String startTimeStr = lineComments[0];int startTime = TimeUtil.parseInteger(startTimeStr);
line.setStartTime(startTime);/合肥市最低工資標(biāo)準(zhǔn)2019/歌詞String lineLyricsStr = lineComments[1]; line.setLineLyrics(lineLyricsStr);
return line; }returnnull;}
歌詞繪制不同的平臺也不一樣,我們這里是Android,所以繪制用Canvas我們這里的思路是:歌詞View的高度是固定的,由于我們希望當(dāng)前行歌詞始終顯示到歌詞View中間,所以先算出View的中心高度,然后在該位置繪制當(dāng)前行歌詞,這一步根據(jù)不同的歌詞處理的邏輯也不一樣,但歌詞可分為兩類,一類是逐行,一類是逐字,對于逐行來說就直接繪制就行了,只是顏色,大小不一樣而已;逐字下合肥市最低工資標(biāo)準(zhǔn)2019一節(jié)講解;然后從當(dāng)前行歌詞位置像前繪制歌詞,直到超出View頂部為止,在從當(dāng)前行歌詞向下歌詞繪制,直到超出View底部為止;當(dāng)前你可以使用LinearLayout添加所有歌詞當(dāng)前容器內(nèi),然后滾動。
privatevoiddrawLyricText(Canvas canvas) {//在當(dāng)前位置繪制正在演唱的歌詞 Line line = lyricsLines.get(lineNumber);
//當(dāng)前歌詞的寬高float textWidth = getTextWidth(backgroundTextPaint, line.getLineLyrics());float textHeight =合肥市最低工資標(biāo)準(zhǔn)2019 getTextHeight(backgroundTextPaint);
float centerY = (getMeasuredHeight() - textHeight) / 2 + lineNumber * getLineHeight(backgroundTextPaint) - offsetY;
float x = (getMeasuredWidth() - textWidth) / 2;float y = centerY;//當(dāng)前歌詞高亮if (lyric.isAccurate()) {//TODO 精確到字,歌詞,下一節(jié)講解
} else {//精確到行 canvas.dr合肥市最低工資標(biāo)準(zhǔn)2019awText(line.getLineLyrics(), x, y, foregroundTextPaint); }//繪制前面的歌詞
for (int i = lineNumber - 1; i > 0; i--) {//從當(dāng)前行的上一行開始繪制 line = lyricsLines.get(i);//當(dāng)前歌詞的寬高 textWidth = getTextWidth(backgroundTextPaint, line.getLineLyrics());
textHeight = getTextHeight(backgroundTextPaint); 合肥市最低工資標(biāo)準(zhǔn)2019 x = (getMeasuredWidth() - textWidth) /
2; y = centerY - (lineNumber - i) * getLineHeight(backgroundTextPaint);if (y < getLineHeight(backgroundTextPaint)) {
//超出了View頂部,不再繪制break; } canvas.drawText(line.getLineLyrics(), x, y, backgroundTextPaint);
}//繪制后面的歌詞for (int i = lineNumber 合肥市最低工資標(biāo)準(zhǔn)2019+ 1; i < lyricsLines.size(); i++) {//從當(dāng)前行的下一行開始繪制 line = lyricsLines.
get(i);//當(dāng)前歌詞的寬高 textWidth = getTextWidth(backgroundTextPaint, line.getLineLyrics()); textHeight = getTextHeight(backgroundTextPaint);
x = (getMeasuredWidth() - textWidth) / 2; y = centerY + (i - lineNumb合肥市最低工資標(biāo)準(zhǔn)2019er) * getLineHeight(backgroundTextPaint);
if (y + getLineHeight(backgroundTextPaint) > getHeight()) {//超出了View底部,不再繪制break; } canvas.drawText(line.getLineLyrics(), x, y, backgroundTextPaint);
}}
歌詞滾動Android中不同的實(shí)現(xiàn)方法滾動方式也不一樣,如果是直接繪制,那么滾動其實(shí)就是繪制不同行歌詞,給人的感覺就是滾動了;如果是將所有歌詞添加到容器中,那么就可以使用容器默認(rèn)的滾動;對合肥市最低工資標(biāo)準(zhǔn)2019于我們這里的實(shí)現(xiàn)滾動其實(shí)就是更改lineNumber值,例如;當(dāng)前l(fā)ineNumber為5,表示當(dāng)前播放的是第5行歌詞,通過用戶滾動的距離就能計(jì)算出當(dāng)前滾動距離是哪一行,因?yàn)槲覀冎烂恳恍懈叨人钥梢杂?jì)算出當(dāng)前位置,滾動到的位置,然后使用屬性動畫滾動:
if (valueAnimator != null && valueAnimator.isRunning()) { valueAnimator.cancel();}valueAnimator = ValueAnimator.ofFloat(offsetY, distanceY);
valueAnimator.addUpdateListener合肥市最低工資標(biāo)準(zhǔn)2019(new ValueAnimator.AnimatorUpdateListener() {@OverridepublicvoidonAnimationUpdate
(ValueAnimator valueAnimator){ offsetY = (float) valueAnimator.getAnimatedValue(); invalidate();
}});valueAnimator.setDuration(200);valueAnimator.setInterpolator(new DecelerateInterpolator());valueAnimator.合肥市最低工資標(biāo)準(zhǔn)2019start();
到這里L(fēng)RC歌詞View核心功能基本就實(shí)現(xiàn)完成了 推薦↓↓↓
長按關(guān)注??【16個(gè)技術(shù)公眾號】都在這里!涵蓋:程序員大咖、源碼共讀、程序員共讀、數(shù)據(jù)結(jié)構(gòu)與算法、黑客技術(shù)和網(wǎng)絡(luò)安全、大數(shù)據(jù)科技、編程前端、Java、Python、Web編程開發(fā)、Android、iOS開發(fā)、Linux、數(shù)據(jù)庫研發(fā)、幽默程序員等。