需要知道的技术点:
1.着色器
android中的着色器shader是非常有用接口。
例如现在多数的圆角图片还有类似flash效果文字都是有着色器功能完成。
着色器为画笔Paint的成员变量,在画笔绘制文字或者图片的是否起到渲染的作用。可以是边框形状渲染,或者颜色,渐变色等渲染。
2.属性动画
在渐变色渲染过程中,渠道渲染的时间线就是属性动画的执行时间线,注意成员变量的值的类型与初始化动画对象的方法要一致,否则不会执行。
3.小坑
TileMode的CLAMP指的是如果当前渲染器在控件外部的话,那么控件剩余的颜色有颜色数组中最后位置的那个颜色填充,由于当前控件式TextView所以一开始文字颜色由gray填充。
在控件显示过程中,onSizeChanged方式被调用一次而onLayout方法被调用两次,所以在onSizeChanged方法中完成了着色器以及动画的初始化。
移动距离最好设置为动画执行过程中增量的2倍,避免出现边界的字显得没有高亮,使得全部字都高亮一遍。
—-代码是基于Shimmer写的,有问题了再去研究他的代码去吧。
private Context context;
private TextPaint paint;
private LinearGradient linearGradient;
private Matrix matrix;
private ObjectAnimator objectAnimator;
private boolean isInvoke = false;
private float gradientX;
public float getGradientX() {
return gradientX;
}
public void setGradientX(float gradientX) {
this.gradientX = gradientX;
System.out.println("setGradientX");
invalidate();
}
public FlashTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
paint = getPaint();
matrix = new Matrix();
}
// 为什么要在onSizeChanged中实现而不在onLayout中实现?因为onLayout中被调用了两次,而onSizeChanged中被调用一次,不明白为什么,但是打印日志确实是这样。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
objectAnimator = ObjectAnimator.ofFloat(this, "gradientX", 0,
getWidth());
objectAnimator.setDuration(1000);
objectAnimator.setRepeatCount(ObjectAnimator.INFINITE);
linearGradient = new LinearGradient(-getWidth(), 0, 0, 0, new int[] {
Color.GRAY, Color.WHITE, Color.GRAY }, new float[] { 0f,
0.5f, 1f }, TileMode.CLAMP);
linearGradient.setLocalMatrix(matrix);
paint.setShader(linearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!isInvoke) {
animate.run();
}
matrix.setTranslate(2 * gradientX, 0);
linearGradient.setLocalMatrix(matrix);
}
private Runnable animate = new Runnable() {
@Override
public void run() {
isInvoke = true;
objectAnimator.start();
}
};