以前看到过有进度条是填充文字的,好奇心作祟,便想自己写一个试试,但是还是比较粗糙,进度条末端没有水流等涌动的效果。
两个控件都是继承TextView,便于设置字体大小等相关属性。
1,GradientTextView 渐变颜色的文字控件
主要用到LinearGradient类,用于渐变颜色,
new LinearGradient(0, 0, width, height, colorArrays[colorIndex], gradientSpread, Shader.TileMode.MIRROR);
参数对应如下,
参数1,参数2:渐变色起点位置。
参数3,参数4:渐变色终点位置。
参数5:渐变色的渐变颜色数组
参数6:渐变色的分布数组(需要和参数5中数组长度相同)
参数7:着色器模式
例子中定时替换渐变色数组colorArrays来达到文字颜色闪动的效果。
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.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.widget.TextView;
/**
* @author jayce
* @date 2015/1/23
*/
public class GradientTextView extends TextView {
private int[] colorArray1 = new int[]{Color.RED, Color.GREEN, Color.BLUE};
private int[] colorArray2 = new int[]{Color.GREEN, Color.BLUE, Color.RED};
private int[] colorArray3 = new int[]{Color.BLUE, Color.RED, Color.GREEN};
private int[][] colorArrays = new int[][]{colorArray1, colorArray2, colorArray3};
private int colorIndex = 0;
private float[] gradientSpread = new float[]{0, 0.5f, 1.0f};
private static final int COLORINVALIDATE=0;
private int width;
private int height;
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
colorIndex = (colorIndex + 1) % 3;
invalidate();
}
};
public GradientTextView(Context context) {
this(context, null);
}
public GradientTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GradientTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
width = getMeasuredWidth();
height = getMeasuredHeight();
}
@Override
protected void onDraw(Canvas canvas) {
//super.onDraw(canvas);
Paint paint = getPaint();
paint.setAntiAlias(true);
LinearGradient lg = new LinearGradient(0, 0, width, height, colorArrays[colorIndex], gradientSpread, Shader.TileMode.MIRROR);
paint.setShader(lg);
canvas.drawText(getText().toString(), 0, height, paint);
handler.sendEmptyMessageDelayed(COLORINVALIDATE,500);
}
}
2,GradientTextViewProgress
在onDraw()中drawText,注意drawText中 canvas.drawText(getText().toString(), 0, baseline, paint);
参数3是baseline的高度。
先用背景画笔画出背景文字,然后用另外一个画笔画出进度,调用canvas.clipRect来裁剪。每次设置进度后,刷新控件。
package huwei.com.gradienttextviewdemo;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.view.View;
import android.widget.TextView;
/**
* @author jayce
* @date 2015/1/23
*/
public class GradientTextProgress extends TextView {
private String mText;
private int maxValue;
private int curValue;
private Paint bgPaint,paint;//<»±Ê
private int mWidth, mHeight, baseline;
private int bgColorInt=Color.BLACK;
private int proColorInt=Color.BLUE;
private LinearGradient lg; //½¥±äÉ«
private boolean hasGradient;
private int[] color;
private float[] position;
private Shader.TileMode mode;
public GradientTextProgress(Context context) {
this(context, null);
}
public GradientTextProgress(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GradientTextProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initPaint();
mText = getText().toString();
}
private void initPaint() {
bgPaint = getPaint();
bgPaint.setAntiAlias(true);
bgPaint.setTextSize(getTextSize());
paint=new Paint();
paint.set(bgPaint);
}
public int getMaxValue() {
return maxValue;
}
public void setMaxValue(int maxValue) {
this.maxValue = maxValue;
}
public String getmText() {
return mText;
}
public void setmText(String mText) {
this.mText = mText;
invalidate();
}
public int getProgress() {
return curValue;
}
public void setLinearGradient(int color[],float position[],Shader.TileMode mode) {
hasGradient=true;
this.color=color;
this.position=position;
this.mode=mode;
}
public void setProgress(int curValue) {
this.curValue = curValue;
invalidate();
}
public int getBgColorInt() {
return bgColorInt;
}
//ÉèÖýø¶È»±ÊÑÕÉ«£¬ÉèÖý¥±äÉ«ºó£¬¸ÃÏîʧЧ
public int getProColorInt( ) {
return proColorInt;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
Paint.FontMetricsInt fontMetrics = paint.getFontMetricsInt();
baseline = (mHeight - fontMetrics.bottom + fontMetrics.top) / 2 - fontMetrics.top;
}
@Override
protected void onDraw(Canvas canvas) {
if (null == mText || "".equals(mText)) return;
bgPaint.setColor(bgColorInt);
canvas.drawText(mText, 0, baseline, bgPaint); //»±³¾°
float section = (float) curValue / maxValue;
Rect proRect = new Rect(0, 0, (int) (section * mWidth), mHeight);
if(!hasGradient){
paint.setColor(proColorInt);
}else{
lg=new LinearGradient(0,0,(int) (section * mWidth),mHeight,color,position, mode);
paint.setShader(lg);
}
canvas.save();
canvas.clipRect(proRect);
canvas.drawText(mText, 0, baseline, paint);
canvas.restore();
}
}