继承TextView自定义LyricView

import java.util.List;    import com.anjoyo.musicplayer.bean.LyricBean;    import android.content.Context;  import android.graphics.Canvas;  import android.graphics.Color;  import android.graphics.LinearGradient;  import android.graphics.Paint;  import android.graphics.Shader;  import android.graphics.Typeface;  import android.graphics.Paint.Align;  import android.graphics.Shader.TileMode;  import android.util.AttributeSet;  import android.widget.TextView;    public class LyricView extends TextView {        /** 控件的高 */      private float mHeight;      /** 控件的宽 */      private float mWidth;      private Paint mPaint;      private Paint prePaint;      private Paint nextPaint;            /** 当前歌曲的歌词 */      private List lyricBeanList;      /** 歌词进度,List中的位置 */      private int index;            private float heightSign;      private boolean start;            private Shader inShader = new LinearGradient(0, 0, 0, LYRIC_ONE_HEIGHT,               Color.argb(0xcc, 0xcc, 0xcc, 0xcc),               Color.argb(0xff, 0xff, 0xff, 0xff), TileMode.MIRROR);      private Shader outShader = new LinearGradient(0, LYRIC_ONE_HEIGHT, 0, 0,               Color.argb(0xcc, 0xcc, 0xcc, 0xcc),               Color.argb(0xff, 0xff, 0xff, 0xff), TileMode.MIRROR);            /** 歌词显示的字体大小 */      private static final int LYRIC_TEXT_SIZE = 36;      /** 每行歌词的高度 */      private static final int LYRIC_ONE_HEIGHT = 60;            public LyricView(Context context) {          super(context);          initView();      }        public LyricView(Context context, AttributeSet attrs, int defStyle) {          super(context, attrs, defStyle);          initView();      }        public LyricView(Context context, AttributeSet attrs) {          super(context, attrs);          initView();                    new UpdateThread().start();      }            private void initView() {          setFocusable(true);                     mPaint = new Paint();          mPaint.setAntiAlias(true);// 设置画笔的锯齿效果          mPaint.setTextAlign(Align.CENTER);          mPaint.setTextSize(LYRIC_TEXT_SIZE);          mPaint.setTypeface(Typeface.SERIF);                    prePaint = new Paint(mPaint);          prePaint.setShader(outShader);          nextPaint = new Paint(mPaint);          nextPaint.setShader(inShader);      }            @Override      protected void onDraw(Canvas canvas) {          super.onDraw(canvas);          if (canvas == null) {              return;          }          mPaint.setColor(Color.argb(0xff, 0xff, 0xff, 0xff));//当前歌词词句颜色          if (lyricBeanList == null || lyricBeanList.size() < 1 || index > lyricBeanList.size() - 1) {              canvas.drawText("好音质,MusicPlayer!", mWidth / 2, mHeight / 2, mPaint);              return;          }          canvas.drawText(lyricBeanList.get(index).getLyric(), mWidth / 2, heightSign, mPaint);                    mPaint.setColor(Color.argb(0xcc, 0xcc, 0xcc, 0xcc));//非当前歌词词句颜色                    float currentY = heightSign;          //画出本句之前的歌词          for (int i = index - 1; i >= 0; i--) {              currentY -= LYRIC_ONE_HEIGHT;              if (i == index - 1) {                  canvas.drawText(lyricBeanList.get(i).getLyric(), mWidth / 2,                          currentY, prePaint);              } else {                  canvas.drawText(lyricBeanList.get(i).getLyric(), mWidth / 2,                          currentY, mPaint);              }          }          currentY = heightSign;          //画出本句之后的歌词          for (int i = index + 1; i < lyricBeanList.size(); i++) {              currentY += LYRIC_ONE_HEIGHT;              if (i == index + 1) {                  canvas.drawText(lyricBeanList.get(i).getLyric(), mWidth / 2,                          currentY, nextPaint);                 } else {                  canvas.drawText(lyricBeanList.get(i).getLyric(), mWidth / 2,                          currentY, mPaint);                    }          }      }            public void setLyricList(List lyricBeanList) {          this.lyricBeanList = lyricBeanList;      }            public void setStart(boolean start) {          this.start = start;      }            public boolean getStart() {          return this.start;      }            public void setIndex(int index) {          if (this.index != index) {              this.index = index;              heightSign = mHeight / 2 + LYRIC_ONE_HEIGHT / 2;          }      }            private class UpdateThread extends Thread {          @Override          public void run() {              while (true) {                  if (start && lyricBeanList.size() > index + 1) {                      if (heightSign > mHeight / 2f - LYRIC_ONE_HEIGHT / 2f) {                          heightSign -= LYRIC_ONE_HEIGHT /                                   (float)(lyricBeanList.get(index + 1).getLyricTime()                                           - lyricBeanList.get(index).getLyricTime()) * 50;                      }                      postInvalidate();                  }                  try {                      sleep(50);                  } catch (InterruptedException e) {                      e.printStackTrace();                  }              }          }      }            @Override      protected void onSizeChanged(int w, int h, int oldw, int oldh) {          super.onSizeChanged(w, h, oldw, oldh);          mWidth = w;          mHeight = h;          heightSign = h / 2f + LYRIC_ONE_HEIGHT / 2f;      }          }

LyricBean.java如下

import java.util.List;    /**  * 一句歌词  *   * @author HLP  */  public class LyricBean {        /** 一句歌词 */      private String lyric;      /** 本句歌词开始的时间 */      private int lyricTime;      /** 本句歌词每个字的持续时间 ,构成数组 */      private List wordsTime;        public LyricBean(String lyric, int lyricTime, List wordsTime) {          super();          this.lyric = lyric;          this.lyricTime = lyricTime;          this.wordsTime = wordsTime;      }        public String getLyric() {          return lyric;      }        public void setLyric(String lyric) {          this.lyric = lyric;      }        public int getLyricTime() {          return lyricTime;      }        public void setLyricTime(int lyricTime) {          this.lyricTime = lyricTime;      }        public List getWordsTime() {          return wordsTime;      }        public void setWordsTime(List wordsTime) {          this.wordsTime = wordsTime;      }    }

有个模拟【天天动听】的项目在GitHub上,需要手机中有MP3歌曲和天天动听格式的歌词,
歌曲和歌词文件名一致,查看请点击

更多相关文章

  1. 动态生成控件
  2. Android(安卓)ArrayListAdapter泛型类
  3. Java - Android(安卓)自定义控件之圆形进度条
  4. Android画一个随意拖动的圆形
  5. android 自带的日期控件 DatePicker
  6. 自定义View组合模式
  7. [控件]SeekBar拖动条
  8. Android(安卓)UI控件-Spinner(下拉列表)
  9. android text 中英文混排 换行的问题

随机推荐

  1. Android(安卓)深入理解Android中的自定义
  2. [置顶] Android开发者社区
  3. NDK 开发指南---Android(安卓)NDK概览
  4. Android中ListView,SQLite,BaseAdapter的结
  5. 关于xmlns:tools和android:onClick使用
  6. (Android(安卓)View)底部导航栏—BottomNav
  7. Android输入密码时显示与隐藏
  8. Android网络开发之WIFI
  9. Android学习笔记(二一):有趣的widget-日期和
  10. android学习方法