读律看书三九年,乌纱头上有青天,男儿欲画凌烟阁,第一功名不爱钱。

不知道大家关注过没有,在你使用支付宝的过程中,有一个支付成功的动画,虽然说很小,但看起来其实还是蛮实用的,涉及的知识点有Android属性动画,Paint的getSegment()函数。

1.分析动画

首先,我们来分析一下这个动画,如上图所示,我们可以看到,先是圆自己运行闭合,然后在在圆的里面画一个✔,对于圆来说,很简单,无外乎定位圆心与半径就行,难点在于✔的设计,所以我们先用一张图来分析一下,如下图所示:

假设圆的半径为mRadius,圆心O坐标为(X,Y),我们把对勾的起点放在A点,假设A的坐标为在圆心平行线中间,那么A的坐标就是(X-mRadius/2,Y),同理,我们假设B的坐标也在圆心垂直线下中心,那么B的坐标为(X,Y+mRadius/2),因为在屏幕中,原点在屏幕的右上角,正方向X轴向右,正方向Y轴向下,所以这里是加,同理,C点肯定要接近圆的边缘,所以C的X轴肯定大于mRadius的一半,姑且我们这里设为X+mRadius/2,而Y也相对来说在上边,而Y不能超出圆外,所以我们根据cX = x + r * cos(a * π / 180);cY = y + r * sin(a * π / 180),计算出该X坐标在圆圈的坐标,小于这个坐标的Y轴设置就行,这里小编C点设置为(x+mRadius/2,Y-mRadius/3)。

2.自定义View

原理我们分析清楚了,下面就可以自定义View,来实现支付宝支付成功的动画了,首先,老样子与刮一刮类似,在Android Studio中间创建一个类继承View,实现如下三个构造函数:

public class AlipayView extends View {public AlipayView(Context context) {super(context);}public AlipayView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);}public AlipayView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}
}

接着我们定义成员变量,如下图所示:

private Paint paint;//画笔工具
private Path circlePath,dstPath;//圆路径,截取路径
private PathMeasure pathMeasure;//计算路径的参数
private float mCurrentValue;//动画执行的进度
private int X,Y,mRadius;//圆心坐标与半径

这里,我们定义了一个画笔工具,两个路径,以及计算路径个参数的计算器类,以及动画执行的进度,所有用到的成员变量都在这里,接着就是初始化我们的AlipayView。

public AlipayView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);setLayerType(LAYER_TYPE_SOFTWARE,null);//关闭硬件加速this.paint=new Paint(Paint.ANTI_ALIAS_FLAG);//初始化画笔,且设置为抗锯齿this.paint.setStrokeWidth(4);//设置画笔宽度this.paint.setStyle(Paint.Style.STROKE);//设置描边this.dstPath=new Path();//初始化this.circlePath=new Path();//初始化this.circlePath.addCircle(X,Y,mRadius,Path.Direction.CW);//顺时针画圆//下面三行代码画的是勾的路径,对照上面分析图this.circlePath.moveTo(X-mRadius/2,Y);this.circlePath.lineTo(X,Y+mRadius/2);this.circlePath.lineTo(X+mRadius/2,Y-mRadius/3);this.pathMeasure=new PathMeasure(this.circlePath,false);//不闭合ValueAnimator valueAnimator=ValueAnimator.ofFloat(0,2);//这里分两段动画,一段画圆,一段画勾valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {@Overridepublic void onAnimationUpdate(ValueAnimator animation) {mCurrentValue=(float)animation.getAnimatedValue();//获取动画进度invalidate();//获取到进度后进行重绘,会调用onDraw(Canvas canvas)}});valueAnimator.setDuration(4000);//每次动画时间valueAnimator.start();//执行动画}

这里我们初始化View主要做了三件事,第一初始化各个成员变量,其二将圆的路径与勾的路径初始化,但并没有绘制,绘制都在onDraw(Canvas canvas)函数里面,第三,初始化动画的参数,第四,获取路径的计算器,计算器包含路径的一些信息(pathMeasure)。

3.onDraw(canvas)绘制动画

初始化各个成员变量以及动画参数后,最后就是要将我们的这些信息,绘制到屏幕上去,而自定义View绘制函数是onDraw(Canvas),代码如下:

private boolean mNext=false;//判断是否指闭合@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.WHITE);//首先绘制背景色为白色if(this.mCurrentValue<1){//初始化函数中说过,mCurrentValue是记录动画的进度的,而小编将动画进度设置为2,(0,1)就是画圆圈,(1,2)就是画对勾//而且mCurrentValue的进度是随机的,并不一定获取到1,所以别拿等等与1来计算,只要大于1就执行画对勾就行float stop=this.pathMeasure.getLength()*this.mCurrentValue;//计算当前进度下路径的百分比,比如,0.25画到圆的4分之一,那么整个圆绘画进度长度就在这里计算得到。//前面说过dstPath是截取路径,比如一张图片长200,我截取一半就有100,同样通过pathMeasure.getSegment就可以截取circlePath的当前进度路径。this.pathMeasure.getSegment(0,stop,dstPath,true);}else{if(!mNext){this.mNext=true;//刚说过了,动画的进度值并不一定会获取到1,有可能直接从0.99跳到1.01,那么没绘制完成的部分,就需要绘制先绘制完成this.pathMeasure.getSegment(0,this.pathMeasure.getLength(),dstPath,true);this.pathMeasure.nextContour();//因为圆与对勾并没有闭合,所以算两个路径,这句代码就是切换到对勾路径上}float stop=this.pathMeasure.getLength()*(this.mCurrentValue-1);//每条进度都是按1算百分比的, 但动画设置的是2,所以减去圆的1,单独计算勾的路径百分比this.pathMeasure.getSegment(0,stop,dstPath,true);}canvas.drawPath(dstPath,paint);//把截取到的路径画出来}

这段首先绘制自定义控件的背景为白色,然后判断动画的进度,如果小于1,执行圆的生成动画,通过PathMeasure.getSegment将截取的路径存储到dstPath中,而当动画进度不小于1的时候, 因为动画的插值器并不一定会获取到1这个值,所以接下来首先做的就是先闭合这个圆,然后通过next.Contour()切换到勾的路径,在根据动画的值绘制勾出来,最后调用canvas将截取的路径画到自定义View上面,也就是屏幕上。

private int X=500,Y=500,mRadius=250;//圆心坐标

当然照搬上面代码肯定什么都没有,因为X,Y,mRaduis,都没有赋值,所以根据自己的需求调整大小,或者设置一个函数,让外部调用设置灵活的X,Y,半径都行,代码如上。

XML布局文件代码如下:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.liyuanjinglyj.alipayapplication.AlipayViewandroid:layout_width="match_parent"android:layout_height="match_parent"/></androidx.constraintlayout.widget.ConstraintLayout>

本文代码Github下载地址:点击下载

Android自定义控件(二)——支付宝支付成功动画相关推荐

  1. 【注释张豪华版 Path酷炫动画】极速get花式Path (支付宝支付成功动画)

    本篇文章已授权微信公众号 hongyangAndroid (鸿洋)独家发布 转载请标明出处: http://blog.csdn.net/zxt0601/article/details/54018970 ...

  2. android监听支付宝支付成功,Andriod监听支付宝收款实现个人支付宝支付接口!附安卓App...

    个人微信支付宝免签约支付解决方案 首先呢,我不会开发安卓App,这款APP是我在酷安网看到的,非常简单的一款APP,安装后填写我们的后端接口(用于接收收款通知的)就可以接收收款通知了.所以就算我们没有 ...

  3. android支付宝支付成功后调其他界面,支付宝支付成功回调地址怎么不改变当前页面?...

    手机端支付宝支付成功后 会有一个回调地址"http://pay.xxx.com/channel/alipayWap/return_url.php?is_success=T&notif ...

  4. 安卓Android轻松完成支付宝支付教程

    介绍 参考安卓Dialog源码,他的builder设计模式实现方式是,使用内部类来实现功能,外部类的作用是通过build()函数,来对内部类进行参数设置,例如setter方法. Buidler设计模式 ...

  5. Android端集成支付宝支付

    Android端集成支付宝支付 1.申请账号及配置变量 支付宝快速接入链接点击打开链接 支付宝扫码或者账号密码登录 下面是支付宝给出的接入介绍 第一步:创建应用并获取APPID 要在您的应用中接入支付 ...

  6. 支付宝支付成功后要重新登录问题解决小记

    问题: 项目A使用项目B的支付宝配置信息,支付成功后,进入到了回调地址中,回调地址中的业务处理代码页执行成功,但是在跳转到商户页面时,跳转到非指定页面(如登录页面)或跳转到指定页面但是要求登录. 原因 ...

  7. 仿支付宝支付成功控件

    仿支付宝支付控件(PathMeasure的应用) 本节介绍的是支付宝支付成功的特效实例,废话不多说,先上图再说: 思路 1.首先对于该效果的实现,我考虑的通过动画的绘制过程,从而截取每一段动画,让控件 ...

  8. 支付宝php异步回调,支付宝支付成功之后异步回调处理

    /** * alipay_notify.php. * User: lvfk * Date: 2017/10/26 0026 * Time: 13:48 * Desc: 支付宝支付成功异步通知 */ i ...

  9. 支付宝回调地址index.php,支付宝支付成功回调地址怎么不改变当前页面?

    手机端支付宝支付成功后 会有一个回调地址"http://pay.xxx.com/channel/alipayWap/return_url.php?is_success=T&notif ...

最新文章

  1. 重试次数配置_TestNG实践——2.用例失败重试
  2. linux钟java运行命令,在java中运行linux命令
  3. 用conda安装虚拟的R环境
  4. 在java中jvm目录_JVM具体在哪个文件夹下的
  5. 九和一 Hidove聚合在线图床PHP源码
  6. 如何在win10搜索计算机,如何在win10电脑的任务栏搜索框中添加地址?
  7. 【APP】取代top工具的Linux运维利器--htop
  8. .net 4.0新特性-自旋锁(SpinLock)
  9. php sjis,【通译】PHP中文字编码变换时使用SJIS-win而非SJIS,使用eucJP-win而非EUC-JP...
  10. 计算机ps相框怎么做,教你用PS给相片加上很漂亮的相框
  11. 【OpenCV】基于Qt的“破产版”全能扫描王
  12. App Store Connect新手指导
  13. python初学第一节课
  14. could not find function 函数名
  15. 帝国CMS教程,使用灵动标签调用上一篇下一篇的文章标题图片的方法
  16. Windows10记一次去掉桌面图标箭头引发的血案:该文件没有与之关联的应用来执行操作,请安装一个程序,若已安装程序,请在默认程序控制面板中创建关联。
  17. Excel的公式:公式基本使用、单元格地址引用、错误值利用、追踪公式利用与追踪错误
  18. Pandas学习——Pandas基础
  19. 我的求职历程-----求职总结
  20. 使用阿里云服务器三分钟搭建网站教程(详细图文详解)

热门文章

  1. vintage、迁移率、滚动率、入催率等概念——看完你就懂了
  2. 【整活】使用海龟画图画一个绿码
  3. MT4/MQL4入门到精通EA教程第八课-MQL语言常用函数(八)-常用时间功能函数
  4. 哈佛梅森学者邹传伟:泡沫与机遇——数字加密货币和区块链金融九问
  5. 苹果 企业开发者账号申请入口
  6. unity3D游戏开发十四之NGUI一
  7. 基于simulink的图像处理算法的建模和仿真
  8. 迪士尼影视动画票房创新高
  9. BaseRepository接口
  10. shell企业面试题练习