import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.widget.TextView;
/*
* @文件名: ShaderTextView
* @创建者: cai
* @创建时间: 2018/3/29 17:14
* @描述: 渐变TextView
TileMode:(一共有三种)
CLAMP:如果渲染器超出原始边界范围,会复制范围内边缘染色(拉伸的是图片最后的那一个像素,并不断重复)。
REPEAT:横向和纵向的重复渲染器图片,平铺(横向 纵向不断重复)。
MIRROR:横向和纵向的重复渲染器图片,这个和REPEAT重复方式不一样,他是以镜像方式平铺(横向纵向不断翻转重复)
RadialGradient:用来进行环形渲染
SweepGradient:扫描渐变—围绕一个中心点扫描渐变就像电影里那种雷达扫描,用来梯度渲染。
ComposeShader:组合渲染,可以和其他几个子类组合起来使用;
*/
public class ShaderTextView
extends TextView {
private static final String TAG = "ShadeTextView";
//动画类型
public static final int MOEV_ANIM_TYPE = 1;
public static final int ROTATE_ANIM_TYPE = 2;
public static final int CUSTOM_ANIM_TYPE = 3;
//渐变类型
public static final int LINEAR_GRADIENT_TYPE = 11;
public static final int RADIAL_GRADIENT_TYPE = 22;
public static final int SWEEP_GRADIENT_TYPE = 33;
private CustomAnimInterface mAnimInterface;
/** 移动距离*/
private int translateWidth;
private Paint paint;
private Matrix matrix;
private Shader mShader = getDefaultLinearGradient();
private int mHeight;
private int mWidth;
private boolean isPlay = false;
private float mDegrees;
private int animType = MOEV_ANIM_TYPE;
public boolean isLock() {
return lock;
}
public void setLock(boolean lock) {
this.lock = lock;
}
private boolean lock = true;
public ShaderTextView(Context context) {
super(context);
}
public ShaderTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ShaderTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
if (!lock){
mWidth = getMeasuredWidth();
paint = getPaint();
//添加渲染
paint.setShader(mShader);
paint.setColor(Color.BLACK);
}
}
public void setShader(Shader shader){
mShader = shader;
}
/**
* 设置渲染方式
* @param type {@link #LINEAR_GRADIENT_TYPE},{@link #RADIAL_GRADIENT_TYPE},{@link #SWEEP_GRADIENT_TYPE}
*/
public void setShader(int type) {
switch (type) {
case LINEAR_GRADIENT_TYPE:
mShader = getDefaultLinearGradient();
break;
case RADIAL_GRADIENT_TYPE:
mShader = getDefaultRadialGradient();
break;
case SWEEP_GRADIENT_TYPE:
mShader = getDefaultSweepGradient();
break;
default:
mShader = getDefaultLinearGradient();
break;
}
requestLayout();
}
@NonNull
public LinearGradient getDefaultLinearGradient() {
measure(0,0);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
return new LinearGradient(0,
0,
mWidth,
mHeight,
new int[]{Color.RED,
Color.GREEN,
Color.MAGENTA},
new float[]{0,
0.5f,
1f},
Shader.TileMode.MIRROR);
}
@NonNull
public RadialGradient getDefaultRadialGradient() {
measure(0,0);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
float radius = mWidth / 2.0f;
if (mHeight > mWidth) {
radius = mHeight / 2.0f;
}
return new RadialGradient(mWidth / 2,
mHeight / 2,
radius,
new int[]{Color.RED,
Color.GREEN,
Color.MAGENTA},
new float[]{0,
0.5f,
1f},
Shader.TileMode.MIRROR);
}
@NonNull
public SweepGradient getDefaultSweepGradient() {
measure(0,0);
mWidth = getMeasuredWidth();
mHeight = getMeasuredHeight();
return new SweepGradient(mWidth / 2,
mHeight / 2,
new int[]{Color.RED,
Color.GREEN,
Color.MAGENTA},
new float[]{0,
0.5f,
1f});
}
public void setPlay(boolean play){
setPlay(play,MOEV_ANIM_TYPE);
}
public void setPlay(int animType){
setPlay(true,animType);
}
/**
* 设置是否播放动画以及动画类型
* @param play
* @param animType 当animType=={@link #CUSTOM_ANIM_TYPE}时,
* 即采用自定义动画时,需实现接口{@link ShaderTextView.CustomAnimInterface},
* 并重写{@link ShaderTextView.CustomAnimInterface#customAnim(Matrix matrix,Shader shader)}方法
*/
public void setPlay(boolean play, int animType) {
isPlay = play;
matrix = new Matrix();
this.animType = animType;
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isPlay) {
switch (animType) {
case MOEV_ANIM_TYPE:
moveAnim();
break;
case ROTATE_ANIM_TYPE:
rotateAnim();
break;
case CUSTOM_ANIM_TYPE:
mAnimInterface.customAnim(matrix,mShader);
break;
default:
moveAnim();
break;
}
}
}
private void moveAnim() {
if (matrix == null) { return; }
translateWidth += mWidth / 10;
//表示刚刚移动 了width个宽度 即 正好包含了整个textview 的时候还原
if (translateWidth > mWidth * 2) {
translateWidth -= mWidth * 2;
}
//移动
matrix.setTranslate(translateWidth, 0);
mShader.setLocalMatrix(matrix);
postInvalidateDelayed(100);
}
private void rotateAnim() {
if (matrix == null) { return; }
mDegrees += 15;
//旋转
matrix.setRotate(mDegrees, mWidth / 2f, mHeight / 2f);
mShader.setLocalMatrix(matrix);
postInvalidateDelayed(100);
}
public void setAnimInterface(CustomAnimInterface animInterface) {
mAnimInterface = animInterface;
}
public static interface CustomAnimInterface{
/**
* 自定义动画
* @param matrix
*/
void customAnim(Matrix matrix,Shader shader);
}
}