安卓路径写字动画

代码

package fei.games.tv.test_justkey.view;

import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.LinearInterpolator;

public class Circle extends View {

    public static final String TAG= Circle.class.getSimpleName();

    TextPaint mPaint;
    ValueAnimator valueAnimator;
    float changeValue = 0.0f;
    Path mPath, dst;
    PathMeasure pathMeasure;
    float sumLength = 0;
    float progress;
    float stopPoint;
    float mPathWidth;
    float mPathHeight;
    Paint.FontMetrics metrics;
    Paint linePaint;

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

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

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

    private void init() {
        mPaint = new TextPaint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(10.0f);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setColor(Color.RED);
        mPaint.setTextSize(200);
        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setStrokeWidth(2.0f);
        linePaint.setStyle(Paint.Style.FILL);
        linePaint.setColor(Color.YELLOW);
        setLayerType(LAYER_TYPE_SOFTWARE, null);
        valueAnimator = ValueAnimator.ofFloat(0, 1);
        valueAnimator.setDuration(2000);
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setRepeatCount(-1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                changeValue = (float) animation.getAnimatedValue();
                drawPath(changeValue);
            }
        });
        mPath = new Path();
        dst = new Path();
//        setPath();
        setText("新年快乐");
        pathMeasure = new PathMeasure();
        pathMeasure.setPath(mPath, false);
        sumLength = pathMeasure.getLength();
        while (pathMeasure.nextContour()) {
            sumLength += pathMeasure.getLength();
        }
    }

    public void start() {
        valueAnimator.start();
    }

    public void setText(String xdd){
        metrics = mPaint.getFontMetrics();
        Log.e(TAG, "setText: "+metrics.leading+","+ metrics.ascent+","+metrics.bottom+","+metrics.descent+","+metrics.top);
        mPaint.getTextPath(xdd,0,xdd.length(),0,-metrics.ascent-20,mPath);
        RectF rectF = new RectF();
        mPath.computeBounds(rectF,false);
        mPathWidth = rectF.width();
        mPathHeight = rectF.height();
        Log.e(TAG, "setText: "+mPathWidth+","+mPathHeight );
    }

    public void setPath() {
        mPath.addCircle(400, 400, 150, Path.Direction.CCW);
        mPath.addCircle(400, 400, 250, Path.Direction.CCW);
        mPath.addCircle(400, 400, 350, Path.Direction.CCW);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        if(ViewGroup.LayoutParams.WRAP_CONTENT==getLayoutParams().width){
            widthSize = (int) mPathWidth+getPaddingLeft()+getPaddingRight();
        }
        if(ViewGroup.LayoutParams.WRAP_CONTENT==getLayoutParams().height){
            heightSize = (int) mPathHeight+getPaddingTop()+getPaddingBottom();
        }
        Log.e(TAG, "onDraw: "+widthSize+"," +heightSize);
        setMeasuredDimension(widthSize,heightSize);
    }

    private void drawPath(float changeValue) {
        if (dst != null) {
            dst.reset();
        } else {
            dst = new Path();
        }
        progress = changeValue;
        stopPoint = sumLength * progress;
        pathMeasure.setPath(mPath, false);

        while (stopPoint > pathMeasure.getLength()) {
            stopPoint -= pathMeasure.getLength();
            pathMeasure.getSegment(0, pathMeasure.getLength(), dst, true);
            if(!pathMeasure.nextContour()){
                break;
            }
        }
        pathMeasure.getSegment(0, stopPoint, dst, true);
        invalidate();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate((getMeasuredWidth()-mPathWidth)/2,(getMeasuredHeight()-mPathHeight)/2);
        canvas.drawPath(dst, mPaint);
        canvas.drawLine(0,getMeasuredHeight()+metrics.top,getMeasuredWidth(),getMeasuredHeight()+metrics.top,linePaint);
        canvas.drawLine(0,getMeasuredHeight()+metrics.ascent,getMeasuredWidth(),getMeasuredHeight()+metrics.ascent,linePaint);
        canvas.drawLine(0,getMeasuredHeight()-metrics.descent,getMeasuredWidth(),getMeasuredHeight()-metrics.descent,linePaint);
        canvas.drawLine(0,getMeasuredHeight()-metrics.bottom,getMeasuredWidth(),getMeasuredHeight()-metrics.bottom,linePaint);
    }
}

效果图

在这里插入图片描述在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值