需要知道的技術點:
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();
}
};