Google ZXing系列讲解(五)——ZXing 仿微信扫描UI
2017-03-02 11:19
330 查看
前言
本篇接续上一篇 Google ZXing系列讲解(四)——ZXing 解决竖屏扫描问题。在上篇文章中,通过zxing官方github中的issue回复,解决了zxing横竖屏都可以扫描条码/二维码问题。仅仅有这个还是不够酷炫, 若扫描界面能像微信那样就好了, 可以的,少年!
本文目标:
- 探索
ViewfinderView如何绘制默认UI
- 仿微信定制ZXing UI
少废话,上代码, 戳这里
默认扫描UI
查看zxing源码,自定义这块是在类 ViewfinderView 中实现。主要是在onDraw方法中处理。
接下来先分析ZXing默认的扫描线,然后再其基础上修改为微信的UI。
默认矩形尺寸的计算
这里暂时不考虑图中的菜单等选项。
抽象为坐标图像为:
这里以横轴演示,左上角为整个手机屏幕的原点,向右延伸为X轴, 向下延伸为Y轴。
在 ViewfinderView ->
onDraw中,先会获取中间frame的尺寸。
Rect frame = cameraManager.getFramingRect();
分析代码发现,ZXing默认的扫描框存在一个范围,最小是240 x 240, 最大的是 1200 x 675, 最大的尺寸是按照 1920 x 1080的 5/8而来的。
private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920 private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080
获得尺寸后,就可以在画布上画出frame的尺寸大小,将周边蒙上阴影!
// Draw the exterior (i.e. outside the framing rect) darkened paint.setColor(resultBitmap != null ? resultColor : maskColor); canvas.drawRect(0, 0, width, frame.top, paint); canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, paint); canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, paint); canvas.drawRect(0, frame.bottom + 1, width, height, paint);
具体的思路按照图上四个区域而来!
默认激光线
// Draw a red "laser scanner" line through the middle to show decoding is active paint.setColor(laserColor); paint.setAlpha(SCANNER_ALPHA[scannerAlpha]); scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length; int middle = frame.height() / 2 + frame.top; canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
默认麻点
扫描过程中,会出现麻点,这个是由如下关键代码段处理!possibleResultPoints = new ArrayList<>(5); lastPossibleResultPoints = currentPossible; paint.setAlpha(CURRENT_POINT_OPACITY); paint.setColor(resultPointColor); synchronized (currentPossible) { for (ResultPoint point : currentPossible) { canvas.drawCircle(frameLeft + (int) (point.getX() * scaleX), frameTop + (int) (point.getY() * scaleY), POINT_SIZE, paint); } } }
仿微信扫描UI
微信扫描UI,需要修改ViewfinderView 以及添加某些资源文件!先来看下微信扫描UI图。仿微信扫描框,需要明确以下几个方面:
- 矩形框大小
- 矩形框四角的图形&颜色
- 扫描动画
矩形框大小
横屏时候, ZXing使用了默认的大小 675 x 1200, 而竖屏时候,ZXing使用了默认大小 240 x 240。关键代码段如下:@CameraManager
public synchronized Rect getFramingRect() { int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH); int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT); int leftOffset = (screenResolution.x - width) / 2; int topOffset = (screenResolution.y - height) / 2; ... ... }
private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) { int dim = 5 * resolution / 8; // Target 5/8 of each dimension if (dim < hardMin) { return hardMin; } if (dim > hardMax) { return hardMax; } return dim; }
矩形框四角的图形&颜色
颜色很好确定,画图形的选择有几种方式- 画8条线
- 画8个矩形
无意中发现这篇文章 一片枫叶专栏, 该作者实现了一个 android-zxingLibrary库,查看该lib中有关画边框的代码,发现使用矩形方式画了8个, 而且使用了
AttributeSet来设计,可以在xml中设置边框的宽高等属性! 下文,会做详细说明
扫描动画
上下移动的线条,使用了图片形式。扫描动画原理很简单, onDraw方法被系统不断的调用,在其中控制到上下移动的距离,以及对距离的判断即可!private void drawScanLight(Canvas canvas, Rect frame) { if (scanLineTop == 0) { scanLineTop = frame.top; } if (scanLineTop >= frame.bottom - 30) { scanLineTop = frame.top; } else { scanLineTop += SCAN_VELOCITY;// SCAN_VELOCITY可以在属性中设置,默认为5 } Rect scanRect = new Rect(frame.left, scanLineTop, frame.right, scanLineTop + 30); canvas.drawBitmap(scanLight, null, scanRect, paint); }
实现步骤
1.attrs文件
在values目录中添加attrs文件, 参考android-zxingLibrary<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="innerrect"> <attr name="inner_width" format="dimension"/> <attr name="inner_height" format="dimension"/> <attr name="inner_margintop" format="dimension" /> <attr name="inner_corner_color" format="color" /> <attr name="inner_corner_length" format="dimension" /> <attr name="inner_corner_width" format="dimension" /> <attr name="inner_scan_bitmap" format="reference" /> <attr name="inner_scan_speed" format="integer" /> <attr name="inner_scan_iscircle" format="boolean" /> </declare-styleable> </resources>
本文并没有使用到所有属性,这些属性在哪里使用,答案是在 工程目录下的layout-> capture.xml
<com.google.zxing.client.android.ViewfinderView android:id="@+id/viewfinder_view" android:layout_width="fill_parent" android:layout_height="fill_parent" app:inner_corner_length="30dp" //四角绿颜色矩形的长度 app:inner_corner_width="5dp" //四角绿颜色矩形的宽度 app:inner_scan_bitmap="@drawable/scanline" //需要添加scanline图片到drawable目录中 app:inner_scan_speed="10" // 扫描线移动距离 app:inner_scan_iscircle="true" /> //扫描过程中是否显示麻点
2.ViewfinderView修改
修改了其中很多内容, 涉及的方法包括:- public ViewfinderView(Context context, AttributeSet attrs)
- private void initInnerRect(Context context, AttributeSet attrs)
- public void onDraw(Canvas canvas)
- private void drawFrameBounds(Canvas canvas, Rect frame)
- private void drawScanLight(Canvas canvas, Rect frame)
关键点都添加了 //add by tan 注释
相关文章推荐
- Google ZXing系列讲解(四)——ZXing 解决竖屏扫描问题
- Google ZXing系列讲解(三)——ZXing 目录结构与主体流程
- UIPro实例讲解之QQ2014 UI模仿系列一
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android--基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android微信扫描二维码登入实现 基于ZXing开源工程
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果
- Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果