android流光动画和流光字体

3,507 阅读2分钟

应广大网友要求上图吧

1663042306051419.gif

流光动画是先写一个TextView,然后上面再覆盖一层FlowingLightView

流光字体是直接用ShineTextView,具体效果就看图吧

Android流光动画,直接上代码

/**
 * 流光动画
 */
public class FlowingLightView extends View {

    private Paint mPaint;
    private Path mPath;
    private LinearGradient mLinearGradient;
    private ValueAnimator mValueAnimator;

    public FlowingLightView(Context context) {
        this(context, null);
    }

    public FlowingLightView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FlowingLightView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint();
        mPath = new Path();
    }

    private void initPointAndAnimator(int w, int h) {
        Point point1 = new Point(0, 0);
        Point point2 = new Point(w, 0);
        Point point3 = new Point(w, h);
        Point point4 = new Point(0, h);

        mPath.moveTo(point1.x, point1.y);
        mPath.lineTo(point2.x, point2.y);
        mPath.lineTo(point3.x, point3.y);
        mPath.lineTo(point4.x, point4.y);
        mPath.close();

        // 斜率k
        float k = 0f * h / w;
        // 偏移
        float offset = 1f * w / 8;
        // 0f - offset * 2 为数值左边界(屏幕外左侧), w + offset * 2为数值右边界(屏幕外右侧)
        // 目的是使光影走完一遍,加一些时间缓冲,不至于每次光影移动的间隔都那么急促
        mValueAnimator = ValueAnimator.ofFloat(0f - offset/2, w + offset/2);
        mValueAnimator.setRepeatCount(-1);
        mValueAnimator.setInterpolator(new LinearInterpolator());
        mValueAnimator.setDuration(8000);
        mValueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float value = (float) animation.getAnimatedValue();
                mLinearGradient = new LinearGradient(value, k * value, value + 2, k * (value + 2),
                        new int[]{Color.parseColor("#00FFE5EE"), Color.parseColor("#FFE5EE"), Color.parseColor("#00FFE5EE")}, null, Shader.TileMode.CLAMP);
                mPaint.setShader(mLinearGradient);
                invalidate();
            }
        });

        mValueAnimator.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        initPointAndAnimator(widthSize, heightSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        mValueAnimator.cancel();
    }
}

android 流光字体

public class ShineTextView extends AppCompatTextView {

    private LinearGradient mLinearGradient;
    private Matrix mGradientMatrix;
    private Paint mPaint;
    private int mViewWidth = 0;
    private int mTranslate = 0;

    public ShineTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        if (mViewWidth == 0) {
            mViewWidth = getMeasuredWidth();
            if (mViewWidth > 0) {
                mPaint = getPaint();
                mLinearGradient = new LinearGradient(
                        0,
                        0,
                        mViewWidth/8,
                        0,
                        new int[]{0xFFFF5997, 0xFFFFE5EE, 0xFFFF5997},
                        null,
                        Shader.TileMode.CLAMP);
                mPaint.setShader(mLinearGradient);
                mGradientMatrix = new Matrix();
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mGradientMatrix != null) {
            mTranslate += mViewWidth / 10;
            if (mTranslate > 1.5 * mViewWidth) {
                mTranslate = -mViewWidth / 2;
            }
            mGradientMatrix.setTranslate(mTranslate, 0);
            mLinearGradient.setLocalMatrix(mGradientMatrix);
            postInvalidateDelayed(100);
        }
    }
}

参考: Android实现流光效果、光影移动效果

Android自定义控件(三)——打造闪闪发光的字体

github.com/3803031/Shi…