1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > android-基于ZXing Android Embedded实现仿微信二维码扫描功能

android-基于ZXing Android Embedded实现仿微信二维码扫描功能

时间:2018-05-13 13:59:22

相关推荐

android-基于ZXing Android Embedded实现仿微信二维码扫描功能

前言:

网上也有非常多基于二维码zxing实现自定义需求,但是搜索了一大圈,都没找到自己想要的那种效果,本文基于综合各大大神资料,自己绘制了一个实现zxing二维码,仿微信实现了双击放大缩小,二维码边角,及去除ZXing Android Embedded原生红线效果,仿微信绘制了线条滚动效果。

eg

导入aar

implementation (‘com.journeyapps:zxing-android-embedded:3.6.0’){ transitive = false }

implementation ‘com.google.zxing:core:3.3.2’

implementation ‘com.tbruyelle.rxpermissions2:rxpermissions:0.9.4@aar’

代码

1.闪光灯

//获取CompoundBarcodeView类private CompoundBarcodeView barcodeView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.qrcode);.....barcodeView = (CompoundBarcodeView) findViewById(R.id.barcode_scanner);....flashlight.setOnClickListener(v -> {if (isLightOn) {//闪光灯关闭barcodeView.setTorchOff();flashlight.setImageResource(R.drawable.light_close);} else {//闪光灯打开barcodeView.setTorchOn();flashlight.setImageResource(R.drawable.light_open);}isLightOn = !isLightOn;});// 如果没有闪光灯功能,就去掉相关按钮if (!hasFlash()) {flashlight.setVisibility(View.GONE);}}

这里主要调用zxing已经给我们写好的接口CompoundBarcodeView下的接口barcodeView.setTorchOn和Off,我们直接引用就可以了。

2.四个边角框

我们看ZXing Android Embedded源码可以知道,我们可以重写DecoratedBarcodeView类的R.layout.zxing_barcode_scanner的布局

/*** Initialize the view with the xml configuration based on styleable attributes.** @param attrs The attributes to use on view.*/private void initialize(AttributeSet attrs) {// Get attributes set on viewTypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.zxing_view);int scannerLayout = attributes.getResourceId(R.styleable.zxing_view_zxing_scanner_layout, R.layout.zxing_barcode_scanner);attributes.recycle();inflate(getContext(), scannerLayout, this);barcodeView = (BarcodeView) findViewById(R.id.zxing_barcode_surface);if (barcodeView == null) {throw new IllegalArgumentException("There is no a com.journeyapps.barcodescanner.BarcodeView on provided layout " +"with the id \"zxing_barcode_surface\

点开之类,我写上备注

<merge xmlns:android="/apk/res/android">//ScaleBarcodeView 这个对应修改整个背景不分(例如放大缩小)<com.example.qrcodeactivity.qrcode.ScaleBarcodeViewandroid:id="@+id/zxing_barcode_surface"android:layout_width="match_parent"android:layout_height="match_parent" />//CustomViewFinderView 这个对应修改扫描框(例如边角,红线部分)<com.example.qrcodeactivity.qrcode.CustomViewFinderViewandroid:id="@+id/zxing_viewfinder_view"android:layout_width="match_parent"android:layout_height="match_parent" />//底部自定义文字<TextViewandroid:id="@+id/zxing_status_view"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom|center_horizontal"android:background="@color/zxing_transparent"android:text="@string/zxing_msg_default_status"android:textColor="@color/zxing_status_text" /></merge>

这里我们要实现去红线和四个角,所以我们要继承ViewfinderView重写ondraw部分代码

/*** desc:重写扫描框类* author:ccw* date:-12-27* time:22:45*/public class CustomViewFinderView extends ViewfinderView {private int screenWidth = 0;private int screenHeight = 0;private RectF buttonRect;private String text_btn = "个性化需求";/*** 重绘时间间隔*/private static long CUSTOME_ANIMATION_DELAY = 16;/*** 边角线颜色*/private int mLineColor = getContext().getResources().getColor(R.color.c_a_green);/*** 线性梯度各个位置对应的颜色值*/private Rect nowScanRect;/*** 边角线厚度 (建议使用dp)*/private float mLineDepth = TypedValue.applyDimension(PLEX_UNIT_DIP, 2f, getResources().getDisplayMetrics());/*** "边角线长度/扫描边框长度"的占比 (比例越大,线越长)*/private float mLineRate = 0.05f;/*** 扫描线起始位置*/private int mScanLinePosition = 0;/*** 扫描线每次重绘的移动距离*/private float mScanLineDy = TypedValue.applyDimension(PLEX_UNIT_DIP, 3f, getResources().getDisplayMetrics());/*** 线性梯度*/private LinearGradient mLinearGradient;/*** 线性梯度位置*/private float[] mPositions = {0f, 0.5f, 1f};/*** 扫描线厚度*/private float mScanLineDepth = TypedValue.applyDimension(PLEX_UNIT_DIP, 1f, getResources().getDisplayMetrics());//扫描线渐变色private int laserColor_center = getContext().getResources().getColor(R.color.c_a_green);private int laserColor_light = getContext().getResources().getColor(R.color.c_a_green);private int[] mScanLineColor = {laserColor_light, laserColor_center, laserColor_light};private float mDist = 0;public CustomViewFinderView(Context context, AttributeSet attrs) {super(context, attrs);init();}private void init() {WindowManager windowManager = ((Activity) getContext()).getWindowManager();DisplayMetrics displayMetrics = new DisplayMetrics();windowManager.getDefaultDisplay().getMetrics(displayMetrics);screenWidth = displayMetrics.widthPixels;screenHeight = displayMetrics.heightPixels;int w = screenWidth * 3 / 5;int marginL = screenWidth / 5;int marginT = screenHeight / 4;nowScanRect = new Rect(marginL, marginT, w + marginL, w + marginT);}@SuppressLint("DrawAllocation")@Overridepublic void onDraw(Canvas canvas) {refreshSizes();if (framingRect == null || previewFramingRect == null) {return;}Rect frame = nowScanRect;// Rect frame = cameraPreview.getFramingRect();Rect previewFrame = previewFramingRect;int width = canvas.getWidth();int height = canvas.getHeight();if (resultBitmap != null) {paint.setColor(resultColor);} else {paint.setColor(maskColor);}canvas.drawRect(0f, 0f, width, frame.top, paint);canvas.drawRect(0f, frame.top, frame.left, (frame.bottom + 1), paint);canvas.drawRect((frame.right + 1), frame.top, width, (frame.bottom + 1), paint);canvas.drawRect(0f, (frame.bottom + 1), width, height, paint);// drawText(canvas, frame)// drawButton(canvas, frame);绘制4个角paint.setColor(mLineColor);//// 定义画笔的颜色//左上-横线canvas.drawRect(frame.left - mLineDepth,frame.top - mLineDepth,frame.left + frame.width() * mLineRate,frame.top, paint);//左上-纵线canvas.drawRect(frame.left - mLineDepth, frame.top, frame.left, frame.top + frame.height() * mLineRate, paint);//右上-横线canvas.drawRect(frame.right - frame.width() * mLineRate, frame.top - mLineDepth, frame.right + mLineDepth, frame.top, paint);//右上-纵线canvas.drawRect(frame.right, frame.top - mLineDepth, frame.right + mLineDepth, frame.top + frame.height() * mLineRate, paint);//左下-横线canvas.drawRect(frame.left - mLineDepth, frame.bottom, frame.left + frame.width() * mLineRate, frame.bottom + mLineDepth, paint);//左下-纵线canvas.drawRect(frame.left - mLineDepth, frame.bottom - frame.height() * mLineRate, frame.left, frame.bottom, paint);//右下-横线canvas.drawRect(frame.right - frame.width() * mLineRate, frame.bottom, frame.right + mLineDepth, frame.bottom + mLineDepth, paint);//右下-纵线canvas.drawRect(frame.right, frame.bottom - frame.height() * mLineRate, frame.right + mLineDepth, frame.bottom + mLineDepth, paint);if (resultBitmap != null) {paint.setAlpha(ViewfinderView.CURRENT_POINT_OPACITY);canvas.drawBitmap(resultBitmap, null, frame, paint);} else {// drawLaserLine(canvas,frame)// 绘制扫描线mScanLinePosition += mScanLineDy;if (mScanLinePosition > frame.height()) {mScanLinePosition = 0;}mLinearGradient = new LinearGradient(frame.left, (frame.top + mScanLinePosition), frame.right, (frame.top + mScanLinePosition), mScanLineColor, mPositions, Shader.TileMode.CLAMP);paint.setShader(mLinearGradient);canvas.drawRect(frame.left, (frame.top + mScanLinePosition), frame.right, frame.top + mScanLinePosition + mScanLineDepth, paint);paint.setShader(null);int scaleX = frame.width() / previewFrame.width();int scaleY = frame.height() / previewFrame.height();List<ResultPoint> currentPossible = possibleResultPoints;List<ResultPoint> currentLast = lastPossibleResultPoints;int frameLeft = frame.left;int frameTop = frame.top;if (currentPossible.isEmpty()) {lastPossibleResultPoints=null;} else {possibleResultPoints = new ArrayList(5);lastPossibleResultPoints = currentPossible;paint.setAlpha(ViewfinderView.CURRENT_POINT_OPACITY);paint.setColor(resultPointColor);for (ResultPoint point : currentPossible) {canvas.drawCircle((frameLeft + (point.getX() * scaleX)), (frameTop + (point.getY() * scaleY)), ViewfinderView.POINT_SIZE, paint);}}if (currentLast != null) {paint.setAlpha(ViewfinderView.CURRENT_POINT_OPACITY / 2);paint.setColor(resultPointColor);float radius = ViewfinderView.POINT_SIZE / 2.0f;for (ResultPoint point : currentLast) {canvas.drawCircle((frameLeft + (point.getX() * scaleX)), (frameTop + (point.getY() * scaleY)), radius, paint);}}}// Request another update at the animation interval, but only repaint the laser line, // not the entire viewfinde// rmask.postInvalidateDelayed(CUSTOME_ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);}private void drawButton(Canvas canvas, Rect mScanRect) {Paint buttonPaint = new Paint();buttonPaint.setAntiAlias(true);buttonPaint.setColor(getContext().getResources().getColor(R.color.c_white));buttonPaint.setStrokeWidth(1f);buttonPaint.setStyle(Paint.Style.STROKE);int height = CommonUtils.dp2px(getContext(), 40);int left = mScanRect.left + (mScanRect.right - mScanRect.left) / 6;int top = mScanRect.bottom + CommonUtils.dp2px(getContext(), 48);int right = mScanRect.right - (mScanRect.right - mScanRect.left) / 6;int bottom = mScanRect.bottom + CommonUtils.dp2px(getContext(), 48) + height;buttonRect = new RectF(left, top, right, bottom);canvas.drawRoundRect(buttonRect, CommonUtils.dp2px(getContext(), 20), CommonUtils.dp2px(getContext(), 20), buttonPaint);buttonPaint.setColor(getContext().getResources().getColor(R.color.c_white));buttonPaint.setTextSize(CommonUtils.dp2px(getContext(), 14));buttonPaint.setStyle(Paint.Style.FILL);buttonPaint.setTextAlign(Paint.Align.CENTER);Paint.FontMetricsInt fontMetrics = buttonPaint.getFontMetricsInt();// var baseLine = buttonRect.centerY() + (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descentint baseLine = (int) ((buttonRect.top + buttonRect.bottom - fontMetrics.top - fontMetrics.bottom) / 2);canvas.drawText(text_btn, buttonRect.centerX(), baseLine, buttonPaint);}

3.0双击放大缩小和双指放大缩小功能

这里我们要实现双击放大缩小和双指放大缩小功能,所以我们要继承BarcodeView重写

public class ScaleBarcodeView extends BarcodeView {private float mDist = 0;//扩展增加双击放大缩小操作 ccwprivate static int timeout = 300;//双击间三百毫秒延时private int clickCount = 0;//记录连续点击次数private Handler handler;public ScaleBarcodeView(Context context) {super(context);}public ScaleBarcodeView(Context context, AttributeSet attrs) {super(context, attrs);handler = new Handler();}public ScaleBarcodeView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouchEvent(MotionEvent event) {int action = event.getAction();if (event.getPointerCount() > 1) {// handle multi-touch eventsif (action == MotionEvent.ACTION_POINTER_DOWN) {mDist = getFingerSpacing(event);} else if (action == MotionEvent.ACTION_MOVE) {CameraInstance cameraInstance = getCameraInstance();if (cameraInstance != null) {cameraInstance.changeCameraParameters(parameters -> {handleZoom(event, parameters);return parameters;});}}} else if (event.getPointerCount() == 1) {if (action == MotionEvent.ACTION_DOWN) {clickCount++;handler.postDelayed(new Runnable() {@Overridepublic void run() {if (clickCount == 2) {CameraInstance cameraInstance = getCameraInstance();if (cameraInstance != null) {cameraInstance.changeCameraParameters(parameters -> {handleScaleZoom(parameters);return parameters;});}}handler.removeCallbacksAndMessages(null);//清空handler延时,并防内存泄漏clickCount = 0;//计数清零}}, timeout);}}return true;}private void handleZoom(MotionEvent event, Camera.Parameters params) {int maxZoom = params.getMaxZoom();int zoom = params.getZoom();float newDist = getFingerSpacing(event);if (newDist > mDist) {//zoom inif (zoom < maxZoom)zoom++;} else if (newDist < mDist) {//zoom outif (zoom > 0)zoom--;}mDist = newDist;params.setZoom(zoom);}private void handleScaleZoom(Camera.Parameters params) {int maxZoom = params.getMaxZoom();int zoom = params.getZoom();if (zoom < maxZoom / 2) {params.setZoom(maxZoom);} else {params.setZoom(1);}}/*** Determine the space between the first two fingers*/private float getFingerSpacing(MotionEvent event) {float x = event.getX(0) - event.getX(1);float y = event.getY(0) - event.getY(1);return (float) Math.sqrt(x * x + y * y);}}

这样就行了,下面我会放上demo,需要的兄弟直接github下载下来研究下,有用到的兄弟姐妹点点关注

点关注不迷路,打个小赏把~~

Github地址: /ccwccw123/android-qrcode/tree/master

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。