android MusicPlayer 音樂播放器 Lrc歌詞控制元件的實現
阿新 • • 發佈:2018-12-30
package com.example.zhsmusicplayer; 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 android.util.Log; /* * 用來讀取歌詞並且解析類 * * */ public class LrcProcess { private List<LrcContent> lrcList;//List集合用來儲存歌詞物件(每一句歌詞) private LrcContent mLrcContent; /* 無引數建構函式*/ public LrcProcess() { mLrcContent = new LrcContent(); lrcList = new ArrayList<LrcContent>(); } /* 讀取某個地址下的歌詞檔案*/ public String readLRC(String path){ StringBuilder stringBuilder = new StringBuilder(); //這裡是直接將MP3的地址直接賦予lrc,及要求lrc的地址與MP3地址一致且名稱與MP3一致 File f = new File(path.replace(".mp3", ".lrc")); //建立一個檔案輸入流 try { //建立一個檔案輸入流物件 FileInputStream fis = new FileInputStream(f); InputStreamReader isr = new InputStreamReader(fis, "utf-8"); BufferedReader br = new BufferedReader(isr); String s = ""; while((s = br.readLine()) != null) { //替換字元 s = s.replace("[", ""); s = s.replace("]", "@"); //分離“@”字元 String splitLrcData[] = s.split("@"); if(splitLrcData.length > 1) { mLrcContent.setLrcStr(splitLrcData[1]); //處理歌詞取得歌曲的時間 int lrcTime = time2Str(splitLrcData[0]); mLrcContent.setLrcTime(lrcTime); //新增進列表陣列 lrcList.add(mLrcContent); //新建立歌詞內容物件 mLrcContent = new LrcContent(); } } } catch (FileNotFoundException e) { e.printStackTrace(); stringBuilder.append("木有歌詞檔案,趕緊去下載!..."); } catch (IOException e) { e.printStackTrace(); stringBuilder.append("木有讀取到歌詞哦!"); } return stringBuilder.toString(); } /** * 解析歌詞時間 * 就是將讀取到的Time轉換為duration */ public int time2Str(String timeStr) { timeStr = timeStr.replace(":", "."); timeStr = timeStr.replace(".", "@"); String timeData[] = timeStr.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; } public List<LrcContent> getLrcList() { return lrcList; } }
<span style="font-family:Arial, Helvetica, sans-serif;"><span style="white-space: normal;"></span></span> 關於File f = new File(path.replace(".mp3", ".lrc")); 這一句是用來讀取某地址下的歌詞檔案,我這裡path引數實際上MP3檔案的地址,這就意味著,我開啟歌詞檔案的地址必須和MP3地址相同,在同一個資料夾且檔名也相同。
接下來就是自定義View作為IrcView了,這裡繼承了TextView,複寫了onDraw()函式來顯示需要的資訊。
<pre name="code" class="java">package com.example.zhsmusicplayer;
import java.util.ArrayList; import java.util.List; 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.util.Log; import android.view.LayoutInflater; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; class CustomBar extends RelativeLayout { private TextView musicName; private ImageView musicImg; private TextView musicArtist; private TextView musicTime; private ImageView iconPlay; private ImageView iconNext; private ImageView iconPrev; private ProgressBar timeBar; public CustomBar(Context context) { super(context); } public CustomBar(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub LayoutInflater inflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); inflater.inflate(R.layout.custom_music_play, this); if(isInEditMode()){return;} musicName=(TextView)findViewById(R.id.name_text); musicArtist=(TextView)findViewById(R.id.author_text); musicTime=(TextView)findViewById(R.id.time_text); musicImg=(ImageView)findViewById(R.id.music_img); iconPlay=(ImageView)findViewById(R.id.play_img); iconNext=(ImageView)findViewById(R.id.next_img); iconPrev=(ImageView)findViewById(R.id.prev_img); timeBar=(ProgressBar)findViewById(R.id.time_progressBar); } public void setMusicName(String name){ musicName.setText(name); } public void setMusicArtist(String Author){ musicArtist.setText(Author); } public void setMusicTime(String time){ musicTime.setText(time); } public void setOnMusicPlayListener(OnClickListener playListener){ iconPlay.setOnClickListener(playListener); } public void setOnMusicPlayNextListener(OnClickListener playNextListener){ iconNext.setOnClickListener(playNextListener); } public void setOnMusicPlayPrevListener(OnClickListener playPrevListener){ iconPrev.setOnClickListener(playPrevListener); } public void setPlayImg(boolean isPause){ if(isPause) iconPlay.setImageResource(R.drawable.icon_pause); else iconPlay.setImageResource(R.drawable.icon_play); } public void setTimeBarMax(int max){ timeBar.setMax(max); } public void setTimeBarProgress(int progress){ timeBar.setProgress(progress); } } class LrcView extends TextView{ private float width; //歌詞檢視寬度 private float height; //歌詞檢視高度 private Paint currentPaint; //當前畫筆物件 private Paint notCurrentPaint; //非當前畫筆物件 private float textHeight = 25; //文字高度 private float textSize = 18; //文字大小 private int index = 0; //list集合下標 private List<LrcContent> mLrcList = new ArrayList<LrcContent>(); public void setmLrcList(List<LrcContent> mLrcList) { this.mLrcList = mLrcList; } public LrcView(Context context) { super(context); init(); } public LrcView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public LrcView(Context context, AttributeSet attrs) { super(context, attrs); init(); } private void init() { setFocusable(true); //設定可對焦 //高亮部分 currentPaint = new Paint(); currentPaint.setAntiAlias(true); //設定抗鋸齒,讓文字美觀飽滿 currentPaint.setTextAlign(Paint.Align.CENTER);//設定文字對齊方式 //非高亮部分 notCurrentPaint = new Paint(); notCurrentPaint.setAntiAlias(true); notCurrentPaint.setTextAlign(Paint.Align.CENTER); } /** * 繪畫歌詞 */ @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); if(canvas == null) { return; } //Log.e("zhs","Index in LrcView Ondraw====="+index); /*if(index!=0) Log.e("zhs",mLrcList.get(index).getLrcStr()); */ //設定字型的大小以及繪製出來的畫筆 currentPaint.setColor(Color.argb(210, 251, 248, 29)); notCurrentPaint.setColor(Color.argb(140, 255, 255, 255)); currentPaint.setTextSize(24); currentPaint.setTypeface(Typeface.SERIF); notCurrentPaint.setTextSize(textSize); notCurrentPaint.setTypeface(Typeface.DEFAULT); try { setText(""); canvas.drawText(mLrcList.get(index).getLrcStr(), width / 2, height / 2, currentPaint); float tempY = height / 2; //畫出本句之前的句子 for(int i = index - 1; i >= 0; i--) { //向上推移 tempY = tempY - textHeight; canvas.drawText(mLrcList.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint); } tempY = height / 2; //畫出本句之後的句子 for(int i = index + 1; i < mLrcList.size(); i++) { //往下推移 tempY = tempY + textHeight; canvas.drawText(mLrcList.get(i).getLrcStr(), width / 2, tempY, notCurrentPaint); } } catch (Exception e) { setText("異常了"); } } /** * 當view大小改變的時候呼叫的方法 */ @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); this.width = w; this.height = h; } public void setIndex(int index) { this.index = index; } }
繪製的原理就是當前index指示的即為當前播放的歌詞為一種Paint,而利用另外一種Paint來繪製出其餘的歌詞。利用setmLrcList(List<LrcContent> mLrcList)函式與setIndex(int index)函式來設定歌詞檔案以及當前index。