一起实现一下用path画一个动画吧(PathMeasure+ValueAnimator)

一直就很想实现一个动画的自定义view研究一阵子之后终于有个小结果了。先上一个图助助兴,然后我们再慢慢道来。

一起实现一下用path画一个动画吧(PathMeasure+ValueAnimator)_第1张图片

gif1

实现起来也比较简单主要通过PathMeasure来测量出每一段路径然后再逐步获取出来通过canvas的draw方法绘制。具体代码如下


import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
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.util.AttributeSet;
import android.util.Log;
import android.view.View;

/**
 * Created by Mr.Xu on 2017/1/8 0008.
 */
public class MyPathView extends View {

    private static final String TAG = MyPathView.class.getSimpleName();
    //画笔
    private Paint mPaint;
    //全部路径
    private Path mPath;
    //测量工具
    private PathMeasure mPathMeasure;
    //实时路径
    private Path mDst;
    //进度
    private float mAnimatorValue;
    //动画
    ValueAnimator valueAnimator;
    public MyPathView(Context context) {
        this(context, null);
    }

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

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setColor(Color.BLUE);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);

        mPath = new Path();
        //设置第一段横线路径
        mPath.moveTo(0, 150);
        mPath.lineTo(150, 150);
        //画圆
        mPath.addArc(new RectF(75, 0, 225, 150), 90, -359);
        mPath.moveTo(150, 150);
        //设置第二段路径
        mPath.lineTo(300, 150);
        //初始化测量工具传入完整路径
        mPathMeasure = new PathMeasure(mPath, false);
        //查看每段路径的长度
        while (mPathMeasure.nextContour()) {
            Log.e(TAG, "length=" + mPathMeasure.getLength());
        }
        //实例化实时路径
        mDst = new Path();
        mDst.reset();
        mDst.lineTo(0, 0);
        //因为上面调用了mPathMeasure.nextContour(),所以需要重置
        mPathMeasure = new PathMeasure(mPath, false);
        //实例化动画
        valueAnimator = ValueAnimator.ofFloat(0, 1);
        //平滑过渡
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            /**
             *
             * @param valueAnimator  0~1
             */
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                mAnimatorValue = (float) valueAnimator.getAnimatedValue();
                //实时路径的百分百比长度0->mPathMeasure.getLength()
                float currentLength = mPathMeasure.getLength() * mAnimatorValue;
                //将对应长度currentLength的路径获取并传递给mDst
                mPathMeasure.getSegment(0, currentLength, mDst, true);
                //重绘
                invalidate();
            }
        });

        valueAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationRepeat(Animator animation) {
                mPathMeasure.getSegment(0, mPathMeasure.getLength(), mDst, true);
                //获取下一段路径
                mPathMeasure.nextContour();
                if (mPathMeasure.getLength() == 0) {
                    //如果全部绘制完成则重置
                    mDst.reset();
                    mDst.lineTo(0, 0);
                    mPathMeasure.setPath(mPath, false);
                }

            }
        });

        valueAnimator.setDuration(1000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.start();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPaint.setColor(Color.RED);
        canvas.drawPath(mDst, mPaint);
    }
}

代码比较简单注释也很详细我就不重复说明了~,学会了之后可以自己实现一些简单的加载动画呢,效果不错。

你可能感兴趣的:(一起实现一下用path画一个动画吧(PathMeasure+ValueAnimator))