Shader着色器的讲解,可以参考
这里LinearGradient的实际运用
先看运行效果
具体思路就是,
- 用LinearGradient设置一个三个字体长度的白色渲染进度条
- 通过setTranslate(offset, 0),设置渲染条的滚动
- postInvalidateDelayed(30),每隔30毫秒刷新界面
完整代码如下:
public class MyLinearGradientTextView extends AppCompatTextView {
private static final String TAG = "MyLinearGradientTextVie";
//textview的宽度
private int mViewWidth = 0;
//画笔
private Paint mPaint;
//线性渲染的宽度 我们设置为三个字体的宽度
private float mGradientWidth;
//线性渲染
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
//滚动偏移量
private int offset;
//滚动速度
private int speed = 15;
public MyLinearGradientTextView(Context context) {
super(context);
}
public MyLinearGradientTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mViewWidth == 0) {
//得到view的宽度
mViewWidth = getWidth();
//代表是有文字的
if (mViewWidth > 0) {
mPaint = getPaint();
//textview的文字
// String text = getText().toString();
//因为我们需要滚动,所以,最好文字个数需要大于mGradientWidth(3个字体长度)长度,才能看出效果
if (getText().length() > 3) {
//每一个文字的长度
float textSize = getTextSize();
//线性渲染的宽度 我们设置为三个字体的宽度
mGradientWidth = 3 * textSize;
} else {
mGradientWidth = mViewWidth;
}
// 从左边0开始,到mGradientWidth滚动扫描过来
mLinearGradient = new LinearGradient(0, 0, mGradientWidth, 0,
new int[]{0x33ffffff, 0xffffffff, 0x33ffffff},
new float[]{0, 0.2f, 1}, Shader.TileMode.CLAMP); //边缘融合
mPaint.setShader(mLinearGradient);
mGradientMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
offset += speed;
/**
* 如果位置已经移动到了整方了那个文字的地就开始往回滚动。
* 但是如果小于1 了那么又开始递增,走另外一个逻辑
*/
if (offset > mViewWidth - mGradientWidth || offset < 1) {
speed = -speed;
}
mGradientMatrix.setTranslate(offset, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
//paint是textview的所以只需要不断色控制画笔的shader 然后利用矩阵控制位移即可
postInvalidateDelayed(30);
}
}