实现支付宝AR扫描效果动画

之前一个网友说想要一个支付宝扫描动画的效果demo,所以又花了点时间做了下这个东西,先看效果图 

说一下实现的思路,如图中最外围的蓝色的是用两个相距180°的圆弧实现的,再往里又是两个红色的圆弧再往里面是一个红色的圆,最里面的白色的是由4个间隔的白色圆弧组成的,其实说明白的就是简单的图形的堆积.然后通过控制绘制圆弧的起始角度进行旋转的动画.扫描的红色线条是一张渐变的图片,通过平移动画实现扫描的效果. 
这个自定义View 的代码如下:

package cn.com.hadon.scanner;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;/*** Created by Mr.Wang on 2017/5/8.*/public class ScanView extends View {private Paint blueCirclePaint;//蓝色圈的画笔private Paint redCirclePaint;//红色圈的画笔private Paint whiteCirclePaint;//白色圈的画笔public static final int STATE_READY = 1;public static final int STATE_SCANING = 2;public static final int STATE_SUCCESS = 3;//定义圆弧的宽度private static final int BLUE_CIRCLE_BORDER_WIDTH = 8;private static final int INSIDER_RED_CIRCLE_BORDER_WIDTH = 20;private static final int OUTSIDER_CIRCLE_BORDER_WIDTH = 20;private static final int WHITE_CIRCLE_BORDER_WIDTH = 20;private int minLength;//中心最大圆的直径private int radius;//中心最大圆的半径private int centerX;//中心点X坐标private int centerY;//中心点Y坐标private Bitmap scanerbitmap;//条形扫描图片private int curState = STATE_SCANING;//初始状态public ScanView(Context context, @Nullable AttributeSet attrs) {super(context, attrs);//初始化一些变量scanerbitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.scaner);blueCirclePaint = new Paint();redCirclePaint = new Paint();whiteCirclePaint = new Paint();blueCirclePaint.setColor(Color.BLUE);blueCirclePaint.setAntiAlias(true);blueCirclePaint.setStyle(Paint.Style.STROKE);blueCirclePaint.setStrokeWidth(BLUE_CIRCLE_BORDER_WIDTH);redCirclePaint.setColor(Color.RED);redCirclePaint.setAntiAlias(true);redCirclePaint.setStyle(Paint.Style.STROKE);redCirclePaint.setStrokeWidth(INSIDER_RED_CIRCLE_BORDER_WIDTH);whiteCirclePaint.setColor(Color.WHITE);whiteCirclePaint.setAntiAlias(true);whiteCirclePaint.setStyle(Paint.Style.STROKE);whiteCirclePaint.setStrokeWidth(WHITE_CIRCLE_BORDER_WIDTH);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);centerX = width / 2;centerY = height / 2;//获取直径和半径以及中心带你坐标方便后面的计算minLength = Math.min(width, height);radius = minLength / 2;}/*** 公开方法设置当前的状态值* @param state*/public void setState(int state) {this.curState = state;}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);canvas.drawColor(Color.TRANSPARENT);switch (curState) {case STATE_READY:drawWhiteCircle(canvas);drawInsiderRedCircle(canvas);drawOutsiderRedCircle(canvas);break;case STATE_SCANING:drawWhiteCircle(canvas);drawBlueCircle(canvas);drawInsiderRedCircle(canvas);drawOutsiderRedCircle(canvas);drawScaner(canvas);break;case STATE_SUCCESS:drawWhiteCircle(canvas);drawInsiderRedCircle(canvas);break;}updateValues();invalidate();}private int blueStartAngle = 0;//蓝色圆圈的开始角度private int blueCircleSpace = BLUE_CIRCLE_BORDER_WIDTH;//蓝色弧距离最短边的距离用于计算自身的半径用private static final int BLUE_CIRCLE_SWEP_ANGLE = 20;//蓝色弧扫过的角度/*** 绘制蓝色弧* @param canvas*/private void drawBlueCircle(Canvas canvas) {canvas.drawArc(centerX - radius + blueCircleSpace, blueCircleSpace, centerX + radius - blueCircleSpace, minLength - blueCircleSpace, blueStartAngle, BLUE_CIRCLE_SWEP_ANGLE, false, blueCirclePaint);canvas.drawArc(centerX - radius + blueCircleSpace, blueCircleSpace, centerX + radius - blueCircleSpace, minLength - blueCircleSpace, blueStartAngle + 180, BLUE_CIRCLE_SWEP_ANGLE, false, blueCirclePaint);}/*** 根据当前的状态来更改变量达到动画的效果*/private void updateValues() {switch (curState) {case STATE_READY:if (insideRedCircleSpace >= BLUE_CIRCLE_BORDER_WIDTH + INSIDER_RED_CIRCLE_BORDER_WIDTH+ OUTSIDER_CIRCLE_BORDER_WIDTH) {insideRedCircleSpace -= 2;}whiteStartAngle = 5 / 2;outsiderRedCircleStartAndle = -OUTSIDER_RED_CIRCLE_SWEP_ANGLE / 2;break;case STATE_SCANING:if (insideRedCircleSpace >= BLUE_CIRCLE_BORDER_WIDTH + INSIDER_RED_CIRCLE_BORDER_WIDTH+ OUTSIDER_CIRCLE_BORDER_WIDTH) {insideRedCircleSpace -= 2;}blueStartAngle += 4;outsiderRedCircleStartAndle += 2;if (is2Max) {if (whiteStartAngle == 30) {is2Max = false;} else {whiteStartAngle++;}} else {if (whiteStartAngle == -30) {is2Max = true;} else {whiteStartAngle--;}}scanerY += 6;if (scanerY > minLength) {scanerY = 0;}break;case STATE_SUCCESS:whiteStartAngle = 5 / 2;if (insideRedCircleSpace < whiteCircleSpace + INSIDER_RED_CIRCLE_BORDER_WIDTH) {insideRedCircleSpace += 2;}break;}}private int insideRedCircleSpace = BLUE_CIRCLE_BORDER_WIDTH + INSIDER_RED_CIRCLE_BORDER_WIDTH + OUTSIDER_CIRCLE_BORDER_WIDTH;private int outsiderRedCircleSpace = BLUE_CIRCLE_BORDER_WIDTH + INSIDER_RED_CIRCLE_BORDER_WIDTH + OUTSIDER_CIRCLE_BORDER_WIDTH / 2;private static final int OUTSIDER_RED_CIRCLE_SWEP_ANGLE = 30;private int outsiderRedCircleStartAndle = -OUTSIDER_RED_CIRCLE_SWEP_ANGLE / 2;/*** 绘制内部的红色圆圈* @param canvas*/private void drawInsiderRedCircle(Canvas canvas) {canvas.drawCircle(centerX, centerY, radius - insideRedCircleSpace, redCirclePaint);}/*** 绘制外部红色的两个弧* @param canvas*/private void drawOutsiderRedCircle(Canvas canvas) {canvas.drawArc(centerX - radius + outsiderRedCircleSpace, outsiderRedCircleSpace, centerX + radius - outsiderRedCircleSpace, minLength - outsiderRedCircleSpace, outsiderRedCircleStartAndle, OUTSIDER_RED_CIRCLE_SWEP_ANGLE, false, redCirclePaint);canvas.drawArc(centerX - radius + outsiderRedCircleSpace, outsiderRedCircleSpace, centerX + radius - outsiderRedCircleSpace, minLength - outsiderRedCircleSpace, outsiderRedCircleStartAndle + 180, OUTSIDER_RED_CIRCLE_SWEP_ANGLE, false, redCirclePaint);}private int whiteStartAngle = 0;private static final int WHITE_CIRCLE_SWEP_ANGLE = 85;private int whiteCircleSpace = BLUE_CIRCLE_BORDER_WIDTH + INSIDER_RED_CIRCLE_BORDER_WIDTH + OUTSIDER_CIRCLE_BORDER_WIDTH + WHITE_CIRCLE_BORDER_WIDTH;private RectF whiteCircleRect;private boolean is2Max = true;/*** 绘制白色的弧* @param canvas*/private void drawWhiteCircle(Canvas canvas) {if (whiteCircleRect == null) {whiteCircleRect = new RectF(centerX - radius + whiteCircleSpace, whiteCircleSpace, centerX + radius - whiteCircleSpace, minLength - whiteCircleSpace);}canvas.drawArc(whiteCircleRect, whiteStartAngle, WHITE_CIRCLE_SWEP_ANGLE, false, whiteCirclePaint);canvas.drawArc(whiteCircleRect, whiteStartAngle + 90, WHITE_CIRCLE_SWEP_ANGLE, false, whiteCirclePaint);canvas.drawArc(whiteCircleRect, whiteStartAngle + 180, WHITE_CIRCLE_SWEP_ANGLE, false, whiteCirclePaint);canvas.drawArc(whiteCircleRect, whiteStartAngle + 270, WHITE_CIRCLE_SWEP_ANGLE, false, whiteCirclePaint);}private int scanerY = 0;/*** 绘制扫描图片* @param canvas*/private void drawScaner(Canvas canvas) {int p1, p2, hw;if (scanerY >= radius) {p1 = (scanerY - radius) * (scanerY - radius);} else {p1 = (radius - scanerY) * (radius - scanerY);}p2 = radius * radius;hw = (int) Math.sqrt(p2 - p1);Rect rect = new Rect(centerX - hw, scanerY - 10, centerX + hw, scanerY + 10);canvas.drawBitmap(scanerbitmap, null, rect, null);}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241

下面是我偶读github地址

完整的demo地址

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wlj644920158/article/details/72865180

实现支付宝AR扫描动画效果相关推荐

  1. android ar 动画,Android实现支付宝AR扫描动画效果

    支付宝AR扫描效果动画实现,具体内容如下 之前一个网友说想要一个支付宝扫描动画的效果demo,所以又花了点时间做了下这个东西,先看效果图 说一下实现的思路,如图中最外围的蓝色的是用两个相距180°的圆 ...

  2. Android 仿支付宝蚂蚁森林动画效果

    Android 动画可以归纳为以下几种: 视图动画(View 动画) 帧动画(Frame 动画.Drawable 动画) 属性动画 触摸反馈动画(Ripple Effect) 揭露动画(Reveal ...

  3. Android 实现人脸识别检测时的扫描动画效果(二维码扫描动画效果同理)

    App现在二维码扫描.人脸扫描的场景越来越多,扫描的动画效果实则就是平移动画:TranslateAnimation 现在我呢用TranslateAnimation实现一个人脸扫描的效果,上下来回滑动( ...

  4. php蚂蚁森林的效果,iOS仿支付宝蚂蚁森林动画效果

    最近要用到类似支付宝蚂蚁森林的动画效果,所以就简单写了一个比较简单的一个demo,效果图如下: 效果图1 需求: 在这个view上面随机出现n个黄钻(button),黄钻按钮还得上下抖动,箭头1指向的 ...

  5. Canvas编程练习:20几行js代码实现雷达扫描动画效果

    灵感源于一不小心挖了一个陈年老贴etherdream发的<[分享]魔兽技能冷却效果(希望能有更好的思路)>的坟,看他的代码太长(约200行),于是自己动手写了一个,也就20多行代码,效果也 ...

  6. SuperMap iObjects .NET 之雷达扫描动画

    作者:贤 目录 1. 介绍 2. 开发环境 3. 流程设计 3.1. 核心逻辑 3.2. 整体流程 4. 代码实现 4.1. 渐变填充雷达扫描区域的扇形 4.2. 定时器刷新实现雷达动态效果 5. 总 ...

  7. Android实现支付宝AR功能,Android RecyclerView 实现支付宝首页效果

    Android RecyclerView 实现支付宝首页效果 [TOC] 虽然我本人不喜欢支付宝的,但是这个网格本身其实还是不错的,项目更新中更改了一个布局为网格模式,类似支付宝.(估计是产品抄袭的= ...

  8. 【SwiftUI模块】0018、SwiftUI搭建一个类似支付宝中的余额宝余额数字动画效果

    SwiftUI模块系列 - 已更新18篇 SwiftUI项目 - 已更新1个项目 往期Demo源码下载 技术:SwiftUI.SwiftUI3.0.支付宝.余额宝.数字动画 运行环境: SwiftUI ...

  9. 高仿支付宝增加减少item功能和动画效果

    闲来无事,看了下支付宝App做的应用item效果,很炫,效果如下: 自己实现的效果如下: gif可能有点卡,但是实现了支付宝效果, 说下思路:下面是实例图(凑合看吧,大概意思是) 开始是打算用Scro ...

最新文章

  1. 稀疏矩阵之python实现
  2. [日志]做人与标点符号
  3. 怎样填写个人简历较有效
  4. 制作JD的手动和自动轮播图片板块
  5. String、StringBuiler、StringBuffer的区别
  6. linux下rsync服务的搭建
  7. 基于confd和etcd的tuxedo中间件容器化方案
  8. 求101到150之间的质数
  9. webstorm识别 ftl文件
  10. 如何通过计算机侵入学校网络,如何进行局域网入侵
  11. python自动喷人工具
  12. 视频教程-微信小程序从入门基础(第一季)-PHP
  13. Linux碎片整理工具,Linux不需要磁盘碎片整理
  14. 基于C++的带权无向图的实现 (三)- Prim最小生成树算法
  15. JS随机漂浮广告代码
  16. APM飞控使用动捕等外部定位
  17. app GPU性能调试笔记
  18. Eclipse之cannot be resolved to a type
  19. windows上配置TensorRT yolov5 -6.0部署 tensorrtx视频流推理
  20. iOS开发——播放系统音效、自定义音效

热门文章

  1. [设备驱动] 最简单的内核设备驱动--字符驱动
  2. 网络期刊(个人使用)
  3. 【报告分享】快手男性消费用户洞察-36Kr磁力引擎(附下载)
  4. Kaggle文本可读性识别大赛银牌方案复盘
  5. TLS1.2的握手过程——从代码角度
  6. 【神经网络】变分自编码大杂烩
  7. backup archivelog all not backed up;
  8. ,英式发音和美式发音有什么区别
  9. 软件测试中遇到的印象深刻的问题及反思
  10. 小米生态链布局遇阻,求快的小米却更慢了