支付宝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); } @Override protected 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; } @Override protected 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); } }
下面是我偶读github地址
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
本文向大家介绍Android中PathMeasure仿支付宝支付动画,包括了Android中PathMeasure仿支付宝支付动画的使用技巧和注意事项,需要的朋友参考一下 前言 在 Android 自定义 View 中,Path 可能用的比较多,PathMeasure 可能用的比较少,就我而言,以前也没有使用过 PathMeasure 这个 api,看到别人用 PathMeasure 和 Valu
本文向大家介绍ASP.NET Core 2.0 支付宝扫码支付的实现代码,包括了ASP.NET Core 2.0 支付宝扫码支付的实现代码的使用技巧和注意事项,需要的朋友参考一下 前言 自从微软更换了CEO以后,微软的战略方向有了相当大的变化,不再是那么封闭,开源了许多东西,拥抱开源社区,.NET实现跨平台,收购xamarin并免费提供给开发者等等。我本人是很喜欢.net的,并希望.net cor
本文向大家介绍Android动画之雷达扫描效果,包括了Android动画之雷达扫描效果的使用技巧和注意事项,需要的朋友参考一下 我们首先看一下效果图,有个整体的印象 好了,为了便于理解,这里就按照动画所见内容依次展开来说 准备 这里决定采用canvas(画布)和paint(画笔)实现了这个简单动画控件。 由图片可以看到有两条交叉的十字线、几个圆圈和一些白点,那么首先定义一下所需的画笔,画布及一些数
本文向大家介绍基于C#实现微信支付宝扫码支付功能,包括了基于C#实现微信支付宝扫码支付功能的使用技巧和注意事项,需要的朋友参考一下 为公司系统业务需要,这几天了解了一下微信和支付宝扫码支付的接口,并用c#实现了微信和支付宝扫码支付的功能。 微信支付分为6种支付模式:1.付款码支付,2.native支付,3.jsapi支付,4.app支付,5.h5支付,6.小程序支付 我在这里用到的是native支
本文向大家介绍java实现在SSM下使用支付宝扫码支付功能,包括了java实现在SSM下使用支付宝扫码支付功能的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了java使用支付宝扫码支付的具体代码,供大家参考,具体内容如下 准备工作 首先开通支付宝沙箱的测试账号,里面会有消费者账户和收款方账户 手机扫码下载手机端app 基础配置 所需jar包 AlipayConfig Controll
本文向大家介绍支付宝支付开发——当面付条码支付和扫码支付实例,包括了支付宝支付开发——当面付条码支付和扫码支付实例的使用技巧和注意事项,需要的朋友参考一下 本文介绍支付宝中当面付下属的条码支付、扫码支付、订单查询、退款申请的集成开发过程。 本文分为以下五个部分: 条码支付和扫码支付介绍 申请应用 密钥生成及配置 API及SDK集成 条码支付、扫码支付、订单查询、退款申请 一、条码支付及二维码支