使用PathMeasure制作Loading动画

动画效果如下:


 

一、PathMeasure使用

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

         PathMeasure()

         PathMeasure(Path path, 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();

boolean getSegment (float startD, float stopD, Path dst, boolean startWithMoveTo)

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


二.Loading动画制作

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

public class LoadingView extends View
{
    private static final int DRAW_CIRCLE = 10001; 
    private static final int ROTATE_TRIANGLE = 10002; 

    private Path mPath;
    private Paint mPaint;
    private PathMeasure mPathMeasure;
    private float mAnimatorValue;
    private Path mDst;
    private float mLength;

    private int mCurrentState = 0;    //当前的状态

    private boolean flag;

    public LoadingView(Context context)
    {
        super(context);
    }

    public LoadingView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(5);
        mPaint.setColor(Color.BLACK);

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

        mPathMeasure = new PathMeasure();
        mPathMeasure.setPath(mPath,true);

        mLength = mPathMeasure.getLength();

        mDst = new Path();

        mCurrentState = DRAW_CIRCLE;

        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0,1);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
        {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator)
            {
                mAnimatorValue = (float) valueAnimator.getAnimatedValue();

                invalidate();
            }
        });

        valueAnimator.setDuration(2000);
        valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
        valueAnimator.setRepeatMode(ValueAnimator.RESTART);
        valueAnimator.start();

        valueAnimator.addListener(new Animator.AnimatorListener()
        {
            @Override
            public void onAnimationStart(Animator animator)
            {

            }

            @Override
            public void onAnimationEnd(Animator animator)
            {

            }

            @Override
            public void onAnimationCancel(Animator animator)
            {

            }

            @Override
            public void onAnimationRepeat(Animator animator)
            {

                switch (mCurrentState){

                    case DRAW_CIRCLE:

                        mCurrentState = ROTATE_TRIANGLE;
                        break;

                    case ROTATE_TRIANGLE:

                        mCurrentState = DRAW_CIRCLE;
                        break;
                }


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

            }
        });



    }

    public LoadingView(Context context, AttributeSet attrs, int defStyleAttr)
    {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        mDst.reset();
        mDst.lineTo(0,0);

        switch (mCurrentState){

            case DRAW_CIRCLE:


                float stop = mLength*mAnimatorValue;

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

                canvas.drawPath(mDst,mPaint);

                break;

            case ROTATE_TRIANGLE:

                canvas.save();

                float start = mLength*mAnimatorValue;

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

                canvas.drawPath(mDst,mPaint);
                break;
        }



    }
}




      

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值