参考文章地址:https://www.jianshu.com/p/a9d09cb7577f
http://blog.youkuaiyun.com/zhangphil/article/details/52004027
安卓闪光字体主要是获取到控件的画笔Paint,然后给Paint添加Shader(渲染效果),将渲染效果平行移动产生闪闪发光的感觉,本文是针对TextView进行重写,按原理,ImageView应该也可以产生相同的效果
先看自定义控件的代码,非常简单
@SuppressLint("AppCompatCustomView")
public class TwinkleTextView extends TextView{
// 线性渐变渲染
private LinearGradient mLinearGradient;
//环形渐变渲染
private RadialGradient mRadialGradient;
// 渲染矩阵
private Matrix mGradientMatrix;
// 画笔
private Paint mPaint;
private int mViewWidth = 0;
private int mViewHeight = 0;
private int mTranslateX = 0;
public TwinkleTextView(Context context) {
super(context);
}
public TwinkleTextView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TwinkleTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public TwinkleTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mViewWidth == 0 || mViewHeight==0) {
mViewWidth = getMeasuredWidth();
mViewHeight=getMeasuredHeight();
if (mViewWidth > 0 || mViewHeight>0 ) {
mPaint = getPaint();
// 创建RadialGradient对象
// 第一个,第二个参数表示渐变圆中心坐标
// 第三个参数表示半径
// 第四个,第五个,第六个与线性渲染相同
mRadialGradient = new RadialGradient(50, 50,30, new int[] {
0x11FEB726, 0xffFEB726, 0x33FEB726 }, new float[] { 0f,
0.5f, 1f}, Shader.TileMode.CLAMP);
// 创建LinearGradient对象
// 起始点坐标(-mViewWidth, 0) 终点坐标(0,0)
// 第一个,第二个参数表示渐变起点 可以设置起点终点在对角等任意位置
// 第三个,第四个参数表示渐变终点
// 第五个参数表示渐变颜色
// 第六个参数可以为空,表示坐标,值为0-1
// 如果这是空的,颜色均匀分布,沿梯度线。
// 第七个表示平铺方式
// CLAMP重复最后一个颜色至最后
// MIRROR重复着色的图像水平或垂直方向已镜像方式填充会有翻转效果
// REPEAT重复着色的图像水平或垂直方向
mLinearGradient = new LinearGradient(-mViewWidth/3, 0, 0, mViewHeight,
new int[] { 0xff000000, 0xffC0C0C0 , 0xff000000 },
new float[] { 0, 0.5f, 1f }, Shader.TileMode.CLAMP);
mPaint.setShader(mLinearGradient);
mPaint.setColor(Color.parseColor("#ff000000"));
//设置字体阴影效果
//第一个参数代表阴影的半径
//第二个参数代表阴影在X方向的延伸像素
//第三个参数代表阴影在Y方向的延伸像素
mPaint.setShadowLayer(3, 2, 2, 0xFFFF00FF);
mGradientMatrix = new Matrix();
}
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if ( mGradientMatrix != null) {
mTranslateX += mViewWidth / 10;
if (mTranslateX > 2 * mViewWidth ) {
mTranslateX = -mViewWidth;
}
mGradientMatrix.setTranslate(mTranslateX, 0);
// mLinearGradient.setLocalMatrix(mGradientMatrix);
mLinearGradient.setLocalMatrix(mGradientMatrix);
postInvalidateDelayed(100);
}
}
}
LinearGradient的构造方法参数较多,下面我们看下都有什么用呢
- xStart: x方向的起点坐标,x,y的起点和终点坐标确定了渐变色的2个属性,1.渐变色平铺时的角度,2.渐变色的宽度;高度不用设置时因为根据宽度和模式,角度铺满控件的
- yStart:Y方向的起点坐标
- xEnd: X方向的终点坐标
- yEnd: Y方向的终点坐标
- int[]: 渐变色数组,三个颜色分别为开始的颜色,中间的颜色,和后面的颜色如 new int[] { 0xff000000, 0xffC0C0C0 , 0xff000001 }
- float[]: 分别指上面三个颜色的位置,如 new float[] { 0, 0.5f, 1f },其中0.5f是指0xffC0C0C0在上面X Y所组成的坐标点的正中间,其他颜色是向两边渐变的,同理1f是指后面的颜色0xff000001在最边缘,其他颜色向中间的颜色渐变(也就是说出国最边缘1f的地方是0xff000001颜色,它左手边的全是渐变色),
- ShaderModle: 渐变平铺的模式,共有三种
-CLAMP 边缘拉伸,如果控件不能被填满,会用后面的颜色覆盖(如0xff000001)
-REPEAT 在水平和垂直两个方向上重复,相邻图像没有间隙
-MIRROR 以镜像的方式在水平和垂直两个方向上重复,相邻图像有间隙
下来我们用图像更形象的看下 坐标 不同带来的角度问题和 三色位置 的影响
我们再看看三种覆盖模式所带来的着色效果
看了上面图片后,想要什么样的效果,自己应该可以随意搭配了,配好想要的效果后,给画笔添加着色器效果,然后就可以在onDraw()方法里面用Matrix对着色的效果进行平移来达到闪光的效果;
最后贴上布局文件的代码,只要引入该布局就可以看到闪闪发光的字体了,是不是很简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.test.caiwen.customview.TwinkleTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Hello World"
android:textSize="35sp"
android:textStyle="bold"
android:background="#ff000000"/>
</LinearLayout>
上述问题如有错误请指正,有更好的想法大家交流分享下