使用PathMeasure制作Loading动画

作者: 小郑 | 来源:发表于2017-05-12 11:10 被阅读100次

    动画效果如下:

    一、PathMeasure使用

    PathMeasure类有两个构造方法,一个带参数,一个不带参数.

    PathMeasure()

    PathMeasure(Pathpath, boolean forceClosed)   官方解释如下:

    Create a PathMeasure object associated with the specified path object (already created and specified). The measure object can now return the path's length, and the position and tangent of any position along the path. Note that once a path is associated with the measure object, it is undefined if the path is subsequently modified and the the measure object is used. If the path is modified, you must call setPath with the path.

    使用PathMeasure和path进行关联,可以追踪Path路径点的坐标,获取Path的长度.

    API

    getLength();

    PathMeasure.getLength()其作用就是获取计算的路径长度。

    getSegment();

    booleangetSegment (floatstartD,floatstopD, Path dst,booleanstartWithMoveTo)

    用于截取整个Path的片段,通过参数startD和stopD来控制截取的长度,并将截取的Path保存到dst中

    二.Loading动画制作

    使用ValueAnimator的ofFloat(0,1)方法,监听从0,1的变化.具体动画代码如下:

    publicclassLoadingViewextendsView

    {

    privatestaticfinalintDRAW_CIRCLE =10001;

    privatestaticfinalintROTATE_TRIANGLE =10002;

    privatePath mPath;

    privatePaint mPaint;

    privatePathMeasure mPathMeasure;

    privatefloatmAnimatorValue;

    privatePath mDst;

    privatefloatmLength;

    privateintmCurrentState =0;//当前的状态

    privatebooleanflag;

    publicLoadingView(Context context)

    {

    super(context);

    }

    publicLoadingView(Context context, AttributeSet attrs)

    {

    super(context, attrs);

    mPaint =newPaint(Paint.ANTI_ALIAS_FLAG);

    mPaint.setStyle(Paint.Style.STROKE);

    mPaint.setStrokeWidth(5);

    mPaint.setColor(Color.BLACK);

    mPath =newPath();

    mPath.addCircle(400,400,100, Path.Direction.CW);

    mPathMeasure =newPathMeasure();

    mPathMeasure.setPath(mPath,true);

    mLength = mPathMeasure.getLength();

    mDst =newPath();

    mCurrentState = DRAW_CIRCLE;

    ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1);

    valueAnimator.addUpdateListener(newValueAnimator.AnimatorUpdateListener()

    {

    @Override

    publicvoidonAnimationUpdate(ValueAnimator valueAnimator)

    {

    mAnimatorValue = (float) valueAnimator.getAnimatedValue();

    invalidate();

    }

    });

    valueAnimator.setDuration(2000);

    valueAnimator.setRepeatCount(ValueAnimator.INFINITE);

    valueAnimator.setRepeatMode(ValueAnimator.RESTART);

    valueAnimator.start();

    valueAnimator.addListener(newAnimator.AnimatorListener()

    {

    @Override

    publicvoidonAnimationStart(Animator animator)

    {

    }

    @Override

    publicvoidonAnimationEnd(Animator animator)

    {

    }

    @Override

    publicvoidonAnimationCancel(Animator animator)

    {

    }

    @Override

    publicvoidonAnimationRepeat(Animator animator)

    {

    switch(mCurrentState){

    caseDRAW_CIRCLE:

    mCurrentState = ROTATE_TRIANGLE;

    break;

    caseROTATE_TRIANGLE:

    mCurrentState = DRAW_CIRCLE;

    break;

    }

    Log.e("mCurrentState",mCurrentState +"");

    }

    });

    }

    publicLoadingView(Context context, AttributeSet attrs,intdefStyleAttr)

    {

    super(context, attrs, defStyleAttr);

    }

    @Override

    protectedvoidonDraw(Canvas canvas)

    {

    mDst.reset();

    mDst.lineTo(0,0);

    switch(mCurrentState){

    caseDRAW_CIRCLE:

    floatstop = mLength*mAnimatorValue;

    mPathMeasure.getSegment(0,stop,mDst,true);

    canvas.drawPath(mDst,mPaint);

    break;

    caseROTATE_TRIANGLE:

    canvas.save();

    floatstart = mLength*mAnimatorValue;

    mPathMeasure.getSegment(start,mLength,mDst,true);

    canvas.drawPath(mDst,mPaint);

    break;

    }

    }

    }

    相关文章

      网友评论

        本文标题:使用PathMeasure制作Loading动画

        本文链接:https://www.haomeiwen.com/subject/qseztxtx.html