1. 程式人生 > >android MusicPlayer 音樂播放器 Lrc歌詞控制元件的實現

android MusicPlayer 音樂播放器 Lrc歌詞控制元件的實現

  
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。