歌词效果制作
首先看一下效果图
大概的思想:先画出颜色为红色的一行文字,測量文字的宽度,假如说是1000,那么截取1000的十分之中的一个的区域,把颜色为蓝色的的一行字画在合格矩形里面。
部分代码例如以下:
package com.example.custom.sz; import com.example.custom.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; /** * * @author 吴传龙 * QQ:312037487 */ public class ColorTrackView extends View { private Context mContext; private String mText; private int mTextSize; private int mTextOriginColor;// 文字原来的颜色 private int mTextChangeColor;// 文字改变的额颜色 private float mProgress; private Paint mPaint; private int mTextRealWidth; public void init(Context context, AttributeSet attrs, int defStyleAttr) { mContext = context; TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.colorTrackView); mText = ta.getString(R.styleable.colorTrackView_text); mTextSize = ta.getDimensionPixelSize( R.styleable.colorTrackView_text_size, mTextSize); mTextOriginColor = ta.getColor( R.styleable.colorTrackView_text_origin_color, mTextOriginColor); mTextChangeColor = ta.getColor( R.styleable.colorTrackView_text_change_color, mTextChangeColor); mProgress = ta.getFloat(R.styleable.colorTrackView_progress, 0); ta.recycle(); mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(mTextOriginColor); mPaint.setTextSize(mTextSize); measureText(); } private int mHeight; @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = measureWidth(widthMeasureSpec); mHeight = measureHeight(heightMeasureSpec); setMeasuredDimension(width, mHeight); } @Override public void draw(Canvas canvas) { super.draw(canvas); mPaint.setColor(Color.RED); canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mPaint.ascent(), mPaint); if (drawTopText){ canvas.save(); mPaint.setColor(Color.BLUE); canvas.clipRect(getPaddingLeft(), 0, mProgress, mHeight); canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mPaint.ascent(), mPaint); canvas.restore(); } } public void measureText() { mTextRealWidth = (int) mPaint.measureText(mText) - getPaddingLeft() - getPaddingRight(); } private boolean drawTopText = false; public void setProgress(final int from, final int to) { new Thread() { public void run() { measureText(); drawTopText = true; int go = 3000 / mTextRealWidth; while(true){ for (int progress = 0; progress < mTextRealWidth;) { mPaint.setColor(mTextChangeColor); progress += go; mProgress = progress; postInvalidate(); try { sleep(100); } catch (InterruptedException e) { } } drawTopText = false; postInvalidate(); drawTopText = true; } }; }.start(); } public int measureWidth(int widthMeasureSpec) { int resultSize; int mode = MeasureSpec.getMode(widthMeasureSpec); int size = MeasureSpec.getSize(widthMeasureSpec); if (mode == MeasureSpec.EXACTLY) { resultSize = size; } else { resultSize = (int) (mPaint.measureText(mText) - getPaddingLeft() - getPaddingRight()); if (mode == MeasureSpec.AT_MOST) { resultSize = Math.min(resultSize, size); } } return resultSize; } public int measureHeight(int heightMeasureSpec) { int resultSize; int mode = MeasureSpec.getMode(heightMeasureSpec); int size = MeasureSpec.getSize(heightMeasureSpec); if (mode == MeasureSpec.EXACTLY) { resultSize = size; } else { resultSize = (int) (mPaint.descent() - mPaint.ascent() + getPaddingTop() + getPaddingBottom()); if (mode == MeasureSpec.AT_MOST) { resultSize = Math.min(resultSize, size); } } return resultSize; } public ColorTrackView(Context context) { this(context, null, 0); } public ColorTrackView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs, defStyleAttr); } public ColorTrackView(Context context, AttributeSet attrs) { this(context, attrs, 0); } }