【开源项目解析】仿支付宝付款成功及天女散花效果实现

话说,在前面两篇文章中,我们学习了BitmapShader、Path的基本使用,那么这一篇文章,咱们接着来学习一下PathMeasure的用法。什么,你没听说过PathMeasure?那你就要OUT咯~

项目效果图

废话不多说,在开始讲解之前,先看下最终实现的效果。

效果一:

仿支付宝支付成功效果

效果二:

这两个项目都是使用Path和PathMeature配合完成的,由其他项目改造而来

项目一是七叔写的,我对代码进行了大量改造。

项目二是不小心搜到的,然后进行了改造,原文请戳这里

本文代码请到这里下载

PathMeasure介绍

PathMeasure这个类确实是不太常见的,关于这个类的介绍也是甚少,那么这个类是用来干嘛的呢?主要其实是配合Path,来计算Path里面点的坐标的,或者是给一个范围,来截取Path其中的一部分的。

这么说,你肯定也迷糊,咱们先简单看一下有哪些方法,然后根据案例来进行讲解更好一些。

构造方法有两个,很好理解,不多解释。

PathMeasure()PathMeasure(Path path, boolean forceClosed)

重点看下常用方法:

仿支付宝实现原理解析

下面,我将介绍一下如何实现下面的这个效果

首先分析需求:

OK,基本就是这些需求,那么对应着需求,咱们看一下解决方案

Canvas.drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,Paint paint) 需要画出来形状,其实就是一些线段,那么就需要用Path了,但是如何能一笔一划的效果呢?那就要靠PathMeasure啦

下面开始讲解代码实现,最好参照着源代码看下面的文章。

首先看怎么用ConfirmView呢?很简单,只需要调用animatedWithState()然后传入一个枚举类型即可

confirmView.animatedWithState(ConfirmView.State.Progressing);

这个枚举类型在类的内部,代表三种状态

public enum State {Success, Fail, Progressing}

再看构造函数,很简单,只是进行了变量的初始化,这些变量的具体作用,我将在下面用到的时候重点介绍

public ConfirmView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);mSuccessPath = new Path();mPathMeasure = new PathMeasure(mSuccessPath, false);mRenderPaths = new ArrayList<>();mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);mPaint.setStyle(Paint.Style.STROKE);mPaint.setColor(0xFF0099CC);mPaint.setStrokeWidth(STROKEN_WIDTH);mPaint.setStrokeCap(Paint.Cap.ROUND);oval = new RectF();}

那么调用了animatedWithState()之后,进行了什么操作呢?

(State state) {if (mCurrentState != state) {mCurrentState = state;if (mPhareAnimator != null && mPhareAnimator.isRunning()) {stopPhareAnimation();}switch (state) {case Fail:case Success:updatePath();if (mCircleAnimator != null && mCircleAnimator.isRunning()) {mCircleAngle = (Float) mCircleAnimator.getAnimatedValue();mCircleAnimator.end();}if ((mStartAngleAnimator == null || !mStartAngleAnimator.isRunning() || !mStartAngleAnimator.isStarted()) &&(mEndAngleAnimator == null || !mEndAngleAnimator.isRunning() || !mEndAngleAnimator.isStarted())) {mStartAngle = 360;mEndAngle = 0;startPhareAnimation();}break;case Progressing:mCircleAngle = 0;startCircleAnimation();break;}}}

结合着上面的代码,我简单解释一下。

首先进行重复性的判断,如果当前所处的状态与要改变的状态相同则不进行操作。

接下来,对动画状态进行了判断,mPhareAnimator是用来实现√和×的动画绘制效果的,如果正在运行,则停掉。

再往下的一个switch则是开始真正的操作了,updatePath()是更新Path,一会重点看下,mCircleAnimator这个则是实现外部弧形的偏移量的控制的,现在看不明白也没事,重点看下下面的代码,当mStartAngleAnimator和mEndAngleAnimator都不在运行状态的时候(这两个Animator是为了控制外部弧形的起点和终点的),会进入下面的代码,

mStartAngle = 360;mEndAngle = 0;startPhareAnimation();

mStartAngle和mEndAngle分别代表起点转过的角度和终点转过的角度,然后就startPhareAnimation(),这个时候,真正的绘制√和×的动画才开始执行。

如果是Progressing呢,则执行下面的代码,重置mCircleAngle,startCircleAnimation()这个方法是绘制外部的弧形的动画

mCircleAngle = 0;startCircleAnimation();

至此,咱们知道了传入不同状态的枚举类型会进行什么操作,下面,开始看真正的操作。

咱先看一个简单的,就是startCircleAnimation()到底做了什么。

前面说过,这个方法是为了绘制加载中状态时,外部不断变化的彩色弧形的,下面是代码实现

() {if (mCircleAnimator == null || mStartAngleAnimator == null || mEndAngleAnimator == null) {initAngleAnimation();}mStartAngleAnimator.setDuration(NORMAL_ANGLE_ANIMATION_DURATION);mEndAngleAnimator.setDuration(NORMAL_ANGLE_ANIMATION_DURATION);mCircleAnimator.setDuration(NORMAL_CIRCLE_ANIMATION_DURATION);mStartAngleAnimator.start();mEndAngleAnimator.start();mCircleAnimator.start();}

首先前面的if语句是为空判断,从而进行初始化的操作,后面则是简单的设置动画的持续时间和开启动画。这里一共出现了三个动画,完成外部弧形的效果控制

从一开始就提醒自己,世上没有后悔药吃。

【开源项目解析】仿支付宝付款成功及天女散花效果实现

相关文章:

你感兴趣的文章:

标签云: