歌词同步的简单处理

MainActivity.java

public class MainActivity extends Activity {
    /**
     * 装歌词的集合
     */
    private ArrayList<String> lrcList;
    /**
     * 装每行歌词的集合
     */
    private ArrayList<Lyric> singleList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 判断SD卡存不存在
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)){
            Toast.makeText(this, "内存卡移除,请插入!", 0).show();
            return;
        }
        lrcList = new ArrayList<String>();
        lrcList=getLrctoString();//得到歌词
        singleList=new ArrayList<Lyric>();
        parserLrc();//解析歌词到singleList
        
        MyView myView=(MyView) findViewById(R.id.myView);
        
        for (Lyric l : singleList) {
            if(l.getLrcString()==null){
                l.setLrcString("");
            }
        }
        myView.init(singleList);
        MediaPlayer mp = MediaPlayer.create(MainActivity.this, R.raw.a);//播放当前工程文件里的音频 sound_file_1为音频文件
         mp.start();
        
    }
    
    /**
     * 切割歌词
     */
    private Lyric spiltString(String current){
        Lyric lrc=new Lyric();
        if(current.contains(":")&&current.contains(".")){
            String[] split = current.split("]");
            if(split.length==2){
                lrc.setLrcString(split[1]);//设置歌词
            }else{
                lrc.setLrcString("");//设置歌词为空
            }
            timeTransform(lrc,split[0].substring(1));
        }
        return lrc;
    }
    
    /**
     * 时间换算  得到显示的时间与维持的时间
     * @param lrc 一行的对象 
     * @param substring  00:00.27 的格式   分钟:秒钟.毫秒
     */
    private void timeTransform(Lyric lrc, String substring) {
        String[] split = substring.trim().split(":");
        int minute=Integer.parseInt(split[0]);//
        String[] spl = split[1].split("\\.");
        int second=Integer.parseInt(spl[0]);//
        int ms=Integer.parseInt(spl[1]);//毫秒
        lrc.setStartTime((minute*60+second)*1000+ms*10);//设置开始的毫秒数
    }

    /**
     * 解析歌词
     */
    private void parserLrc(){
        for (int i = 0; i < lrcList.size(); i++) {
            Lyric lyric = spiltString(lrcList.get(i));
            if(lyric!=null){
                singleList.add(lyric);//还差维持时间
            }
        }
        //将维持时间设置上
        for (int i = 0; i < singleList.size()-1; i++) {
            int sleepTime=singleList.get(i+1).getStartTime()-singleList.get(i).getStartTime();
            singleList.get(i).setSleepTime(sleepTime);
        }
    }
    
    /**
     * 返回歌词
     */
    private ArrayList<String> getLrctoString(){
        try {
            // 获得SD卡的存储目录
            File path = Environment.getExternalStorageDirectory();
            // 获得手机内部存储目录
            //File dataFileDir = Environment.getDataDirectory();
            File file=new File(path+"//Music//老鼠爱大米.lrc");
            BufferedReader br=new BufferedReader(new FileReader(file));
            String line;
            ArrayList<String> list=new ArrayList<String>();
            while((line=br.readLine())!=null){
                list.add(line);
            }
            return list;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

}

MyView.java

public class MyView extends TextView {

    private ArrayList<Lyric> singleList;//歌词
    private int currentLine = 0;//当前行
    private int lineSpacing = 120; //行间距
    
    //当前正在播放的行
    private Paint currentPaint;
    private int currentColor = Color.YELLOW;//颜色
    private int currentSize = 55;//字体大小
    private Typeface currentTypeface = Typeface.DEFAULT_BOLD;//字体,默认的字体+粗体
    //其他行
    private Paint ortherPaint;
    private int ortherColor = Color.BLACK;
    private int ortherSize = 40;
    private Typeface ortherTypeface = Typeface.SERIF;//一种字体类型
    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            currentLine++;//行数自加
            invalidate();
        }
    };
    
    public MyView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    
    
    /**
     * 绘制内容
     */
    @Override
    protected void onDraw(Canvas canvas) {
        if (singleList != null ) {// 避免程序一运行就执行该方法
            if(currentLine<=singleList.size()){
                for (int i = 0; i < singleList.size(); i++) {
                    Lyric lyric = singleList.get(i);
                    if (i == currentLine) {// 当前行,应该显示在正中间
                        canvas.drawText(lyric.getLrcString(), getWidth()/2, getHeight()/2, currentPaint);// 以屏幕正中间为起源
                    } else {// 当前行的其他内容
                        ortherPaint.setAlpha(225-Math.abs((i - currentLine)*30));//设置透明度
                        canvas.drawText(lyric.getLrcString(), getWidth()/2,
                                getHeight()/2 + (i - currentLine) * lineSpacing,//行距,以屏幕中心为参考设置行距
                                ortherPaint);
                    }
                }
                if(currentLine<singleList.size()){
                    //延时当前行维持的时间后发送消息
                    handler.sendEmptyMessageDelayed(1, singleList.get(currentLine).getSleepTime());
                }
            }
        }
    }
    /**
     * 初始化
     */
    public void init(ArrayList<Lyric> singleList){
        this.singleList = singleList;
        currentPaint = new Paint();//当前行
        currentPaint.setColor(currentColor);
        currentPaint.setAntiAlias(true);//打开抗锯齿
        currentPaint.setTextSize(currentSize);
        
        currentPaint.setTextAlign(Align.CENTER);//文字居中对齐
        currentPaint.setTypeface(currentTypeface);//设置字体
        ortherPaint = new Paint();//其他行
        ortherPaint.setColor(ortherColor);
        ortherPaint.setAntiAlias(true);
        ortherPaint.setTextSize(ortherSize);
        ortherPaint.setTextAlign(Align.CENTER);
        ortherPaint.setTypeface(ortherTypeface);
        invalidate();//更新内容,调用onDraw方法
    }
    
    /**
     * 还是没有跑马灯效果
     */
    @Override
    public boolean isFocused() {
        return true;
    }    
}

歌词封装类:Lyric.java

/**
 * 歌词类
 */
public class Lyric {
    /**
     * 开始时间
     */
    private int startTime;
    
    /**
     * 改行歌词占用时间
     */
    private int sleepTime;
    /**
     * 一行的歌词
     */
    private String lrcString;
    public int getStartTime() {
        return startTime;
    }
    public void setStartTime(int startTime) {
        this.startTime = startTime;
    }
    public int getSleepTime() {
        return sleepTime;
    }
    public void setSleepTime(int sleepTime) {
        this.sleepTime = sleepTime;
    }
    public String getLrcString() {
        return lrcString;
    }
    public void setLrcString(String lrcString) {
        this.lrcString = lrcString;
    }
    public Lyric(int startTime, int sleepTime, String lrcString) {
        super();
        this.startTime = startTime;
        this.sleepTime = sleepTime;
        this.lrcString = lrcString;
    }
    public Lyric() {
        super();
    }
    @Override
    public String toString() {
        return "startTime=" + startTime + ", sleepTime=" + sleepTime
                + ", lrcString=" + lrcString;
    }
    
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
<!-- 没有跑马灯效果 -->
    <com.example.mymusic.MyView
        android:background="#ccccff"
        android:singleLine="true"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
       android:id="@+id/myView"/>

</RelativeLayout>

效果图:

posted @ 2016-08-08 21:16  ts-android  阅读(230)  评论(0编辑  收藏  举报