Android Zxing 扫描器 扫描框、扫描线定制样式
2016-07-08 10:59
459 查看
一、概述
相信Adnroid开发都知道,世界上有四款扫描器,Zxing 、Zbar ,Barcode4J、OkapiBarcode 前二者应用较广泛,至于介绍与区别就在此阐述,网上有很多。此文主要介绍在在使用过程中,官方客户端各种达不到需求。相信很多童鞋都有此体会,所以借此机会就在Zxing 官方客户端基础上修改,去除无用功能并二次封装达到可扩展。官方客户端目前问题汇总
设置功能多余
竖屏后不能正向扫描条形码
扫描框大小、颜色、扫描线配置不够灵活
无生成二维码、主动识别二维码功能
介于以上问题,于是该库就华丽的诞生
修复竖屏不能正向扫描条形码
可定制扫描框与扫描线样式
加入创建二维码、识别图片中的二维码功能
二、效果图
本库地址:https://github.com/mylhyl/Android-Zxing
三、代码说明
Zxing 核心代码 https://github.com/zxing/zxing/tree/master/core 不作任何修改也不需要修改,只管用就行主要修改客户端代码。你可以自己编译成 jar 或者直接下源码拷到工程,可以参考Zxing编译。也可以到github下载本库,利用gradle编译如下图双击 makeJar
等待控制出现 BUILD SUCCESSFUL 即编译完成,zxing 工程目录build将出libs目录
精简后的代码,去掉资源文件、扫描历史记录、分享等,目录结构如下
camera 摄像头相关
common 全局静态常量相关
decode 解析二维码相关
encode 生成二维码相关
OnScannerCompletionListener 扫描成功接口
ViewfinderView 扫描预览视图
ScannerView 新增自定义View,包括 ViewfinderView 、SurfaceView,公开一些样式设置方法,具体使用后面介绍
样式定义上来说,其实就在darw方法中,与平时自定义View一样,废话不多说来看一下干货
定义所用的变量
private int laserColor = Scanner.color.VIEWFINDER_LASER;//扫描线颜色 private int laserFrameBoundColor = laserColor;//扫描框4角颜色 private int laserLineTop;// 扫描线最顶端位置 private int laserLineHeight;//扫描线默认高度 private int laserMoveSpeed;// 扫描线默认移动距离px private int laserFrameCornerWidth;//扫描框4角宽 private int laserFrameCornerLength;//扫描框4角高 private int laserLineResId;//扫描线图片资源 private String drawText = "将二维码放入框内,即可自动扫描";//提示文字 private int drawTextSize;//提示文字大小 private int drawTextColor = Color.WHITE;//提示文字颜色 private boolean drawTextGravityBottom = true;//提示文字位置 private int drawTextMargin;//提示文字与扫描框距离
darw方法
@Override public void onDraw(Canvas canvas) { if (cameraManager == null) { return; } Rect frame = cameraManager.getFramingRect();//取扫描框 //取屏幕预览 Rect previewFrame = cameraManager.getFramingRectInPreview(); if (frame == null || previewFrame == null) { return; } // 绘制扫描框以外4个区域 drawMask(canvas, frame); // 如果有二维码结果的Bitmap,在扫取景框内绘制不透明的result Bitmap if (resultBitmap != null) { paint.setAlpha(CURRENT_POINT_OPACITY); canvas.drawBitmap(resultBitmap, null, frame, paint); } else { drawFrame(canvas, frame);//绘制扫描框 drawFrameCorner(canvas, frame);//绘制扫描框4角 drawText(canvas, frame);// 画扫描框下面的字 drawLaserLine(canvas, frame);//绘制扫描线 drawResultPoint(canvas, frame, previewFrame);//绘制扫描点标记 moveLaserSpeed(frame);//计算移动位置 } }
扫描框的4个角
/** * 绘制扫描框4角 * * @param canvas * @param frame */ private void drawFrameCorner(Canvas canvas, Rect frame) { paint.setColor(laserFrameBoundColor); paint.setStyle(Paint.Style.FILL); // 左上角 canvas.drawRect(frame.left - laserFrameCornerWidth, frame.top, frame.left, frame.top + laserFrameCornerLength, paint); canvas.drawRect(frame.left - laserFrameCornerWidth, frame.top - laserFrameCornerWidth, frame.left + laserFrameCornerLength, frame.top, paint); // 右上角 canvas.drawRect(frame.right, frame.top, frame.right + laserFrameCornerWidth, frame.top + laserFrameCornerLength, paint); canvas.drawRect(frame.right - laserFrameCornerLength, frame.top - laserFrameCornerWidth, frame.right + laserFrameCornerWidth, frame.top, paint); // 左下角 canvas.drawRect(frame.left - laserFrameCornerWidth, frame.bottom - laserFrameCornerLength, frame.left, frame.bottom, paint); canvas.drawRect(frame.left - laserFrameCornerWidth, frame.bottom, frame.left + laserFrameCornerLength, frame.bottom + laserFrameCornerWidth, paint); // 右下角 canvas.drawRect(frame.right, frame.bottom - laserFrameCornerLength, frame.right + laserFrameCornerWidth, frame.bottom, paint); canvas.drawRect(frame.right - laserFrameCornerLength, frame.bottom, frame.right + laserFrameCornerWidth, frame.bottom + laserFrameCornerWidth, paint); }
图片画与画笔扫描线
/** * 画扫描线 * * @param canvas * @param frame */ private void drawLaserLine(Canvas canvas, Rect frame) { if (laserLineResId == 0) { paint.setStyle(Paint.Style.FILL); paint.setColor(laserColor);// 设置扫描线颜色 canvas.drawRect(frame.left, laserLineTop, frame.right, laserLineTop + laserLineHeight, paint); } else { if (laserLineBitmap == null)//图片资源文件转为 Bitmap laserLineBitmap = BitmapFactory.decodeResource(getResources(), laserLineResId); int height = laserLineBitmap.getHeight();//取原图高 //网格图片 if (isLaserGridLine) { RectF dstRectF = new RectF(frame.left, frame.top, frame.right, laserLineTop); Rect srcRect = new Rect(0, (int) (height - dstRectF.height()), laserLineBitmap.getWidth(), height); canvas.drawBitmap(laserLineBitmap, srcRect, dstRectF, paint); } //线条图片 else { //如果没有设置线条高度,则用图片原始高度 if (laserLineHeight == Scanner.dp2px(getContext(), DEFAULT_LASER_LINE_HEIGHT)) { laserLineHeight = laserLineBitmap.getHeight() / 2; } Rect laserRect = new Rect(frame.left, laserLineTop, frame.right, laserLineTop + laserLineHeight); canvas.drawBitmap(laserLineBitmap, null, laserRect, paint); } } }
扫描提示文字
/** * 绘制提示文字 * * @param canvas * @param frame */ private void drawText(Canvas canvas, Rect frame) { int width = canvas.getWidth(); paint.setColor(drawTextColor); paint.setTextSize(drawTextSize); final float textWidth = paint.measureText(drawText);//取出文字宽度 float x = (width - textWidth) / 2;//文字开始位置 //根据 drawTextGravityBottom 文字在扫描框上方还是下文,默认下方 float y = drawTextGravityBottom ? frame.bottom + drawTextMargin : frame.top - drawTextMargin; canvas.drawText(drawText, x, y, paint); }
三、使用
直接在layout xml使用
ScannerView即可
<com.mylhyl.zxing.scanner.ScannerView android:id="@+id/scanner_view" android:layout_width="match_parent" android:layout_height="match_parent" />
重写
onResume调用
mScannerView.onResume();
@Override protected void onResume() { mScannerView.onResume(); super.onResume(); }
注册扫描成功监听器
setOnScannerCompletionListener
/** * 扫描成功后将调用 * * @param rawResult 扫描结果 * @param parsedResult 结果类型 * @param barcode 扫描后的图像 */ void OnScannerCompletion(Result rawResult, ParsedResult parsedResult, Bitmap barcode);
调用如下方法获取类型
ParsedResultType type = parsedResult.getType();
可根据
type强转为相应的对象,按项目需求处理。每个项目都有不同的需求,所以此库将最终处理结果丢给你们自己咯,想怎么玩就怎么玩,下面代码是在 sample 中
switch (type) { case ADDRESSBOOK: AddressBookParsedResult addressResult = (AddressBookParsedResult) parsedResult; bundle.putStringArray(Intents.AddressBookConnect.NAME, addressResult.getNames()); bundle.putStringArray(Intents.AddressBookConnect.NUMBER, addressResult.getPhoneNumbers()); bundle.putStringArray(Intents.AddressBookConnect.EMAIL, addressResult.getEmails()); break; case URI: URIParsedResult uriParsedResult = (URIParsedResult) parsedResult; bundle.putString(Intents.URIContents.URI, uriParsedResult.getURI()); break; case TEXT: bundle.putString(Intents.Scan.RESULT, rawResult.getText()); break; }
生成二维码
Bitmap bitmap = QREncode.encodeQR(MainActivity.this, new QREncode.Builder() .setColor(getResources().getColor(R.color.colorPrimary))//二维码颜色 .setParsedResultType(ParsedResultType.URI)//二维码类型 .setContents("https://github.com/mylhyl")//二维码内容 .build()); imageView.setImageBitmap(bitmap);
四、样式设置
方法名 | 说明 | 默认值 |
---|---|---|
toggleLight | 切换闪光灯 | 关 false |
setMediaResId | 设置扫描完成播放声音 | 无 |
setLaserFrameBoundColor | 扫描框4角颜色 | 绿色 0xff00ff00 |
setLaserFrameCornerLength | 扫描框4角长度 | 15dp |
setLaserFrameCornerWidth | 扫描框4角宽度 | 2dp |
setLaserColor | 扫描线颜色 | 绿色 0xff00ff00 |
setLaserLineResId | 条形扫描线图片资源 | 无 |
setLaserGridLineResId | 网格扫描线资源 | 无 |
setLaserLineHeight | 扫描线高度 | 2dp |
setLaserFrameSize | 设置扫描框大小 | 屏幕5/8 |
setLaserFrameTopMargin | 设置扫描框与屏幕距离 | 屏幕5/8-状态 |
setDrawText | text -> 内容 textSize -> 文字大小 textColor -> 文字颜色 isBottom -> 是否在扫描框下方 textMargin -> 离扫描框间距 | text -> 将二维码放入框内,即可自动扫描 textSize -> 16sp textColor -> 白色 isBottom -> true textMargin -> 20dp |
点击加入群
我建了个微信公众号,我们将每天为您推送优质文章、开源库及学习心得,欢迎关注。
相关文章推荐
- Android基于google Zxing实现二维码的生成
- Android基于google Zxing实现各类二维码扫描效果
- Android上使用ZXing识别条形码与二维码的方法
- 详解ZXing-core生成二维码的方法并解析
- Android开发框架之自定义ZXing二维码扫描界面并解决取景框拉伸问题
- Android zxing 二维码使用
- 自定义ZXing二维码扫描界面并解决取景框拉伸等问题
- 基于zxing-lib三步实现Android二维码应用
- Android Zxing条码扫描自定义控件(附代码)
- 项目总结——zxing扫描
- ireport中unable to resolve class com.google.zxing.qrcode.QRCodeWriter问题解决
- 利用googleZxing生成二维码识别二维码
- zxing解码二维码图片
- ZXing二维码的备忘
- ZXing2.2编译方法
- ios开发:zxing 二维码
- JAVA二维码生成
- 条码扫描二维码扫描—ZXing android 改进版本
- Android平台下利用zxing实现二维码开发
- HDU 1542 Atlantis (线段树 +离散化+ 扫描线)