整體效果如圖,有兩種方向的閃動,一種是來回閃動,一種是一個方向閃動
在onSizeChanged
方法中,計算好字符串的實際位置後,新建一個LinearGradient
對象,顏色漸變方式是左、中、右的位置分別對應字體的顏色、閃光的顏色、字體的顏色。
重寫onDraw
方法,設置linearGradient
的位置矩陣matrix
,dx
是矩陣的左右位移。然後設置mPaint
的着色器,這裏的mPaint
即當前繪製的TextView
的Paint對象,可通過調用getPaint()
獲得。最後調用父方法繪製字符串。
單一方向閃動:
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class ShiningFontView extends TextView {
private Paint mPaint;
private LinearGradient mLinearGradient;
private Matrix mGradientMatrix;
private int mViewWidth;
private int mTranslate;
public ShiningFontView(Context context) {
this(context, null);
}
public ShiningFontView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ShiningFontView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mViewWidth == 0) {
mViewWidth = w;
if (mViewWidth > 0) {
mPaint = getPaint();
/**
* LinearGradient構造方法中的參數int[] color:
* 第一個元素:發光字體閃過後所顯示的字體顏色,這裏給定與第三個元素一樣
* 第二個元素:字體發光的顏色
* 第三個元素:原字體顯示的顏色
*
* mViewWidth:設置發光的寬度
* */
mLinearGradient = new LinearGradient(0, 0, mViewWidth, 0, new int[]{0x22ffffff, 0xffffffff, 0x22ffffff}, null, Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
mGradientMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mGradientMatrix != null) {
mTranslate += mViewWidth / 5;
if (mTranslate > mViewWidth * 2) {
mTranslate = -mViewWidth;
}
mGradientMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mGradientMatrix);
//控制閃過的時間
postInvalidateDelayed(80);
}
}
}
來回兩個方向閃動:
// 3個文字的寬度
int gradientSize = (int) (textWith / text.length() * 3);
// 從左邊-gradientSize開始,即左邊距離文字gradientSize開始漸變
mLinearGradient = new LinearGradient(-gradientSize, 0, 0, 0, new int[]{
0x22ffffff, 0xffffffff, 0x22ffffff}, null, Shader.TileMode.CLAMP
);
mPaint.setShader(mLinearGradient);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
mTranslate += DELTAX;
float textWidth = getPaint().measureText(getText().toString());
//到底部進行返回
if (mTranslate > textWidth + 1 || mTranslate < 1) {
DELTAX = -DELTAX;
}
mMatrix = new Matrix();
mMatrix.setTranslate(mTranslate, 0);
mLinearGradient.setLocalMatrix(mMatrix);
postInvalidateDelayed(50);
}
}