com.journeyapps.barcodescanner.WXViewfinderView.java Source code

Java tutorial

Introduction

Here is the source code for com.journeyapps.barcodescanner.WXViewfinderView.java

Source

/*
 * Copyright (C) 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.journeyapps.barcodescanner;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.support.v4.content.res.ResourcesCompat;
import android.util.AttributeSet;
import android.view.View;

import com.google.zxing.client.android.R;

/**
 * This view is overlaid on top of the camera preview. It adds the viewfinder rectangle and partial
 * transparency outside it, as well as the laser scanner animation and result points.
 *
 * @author dswitkin@google.com (Daniel Switkin)
 */
public class WXViewfinderView extends View {
    protected static final String TAG = WXViewfinderView.class.getSimpleName();

    protected Paint maskPaint;
    protected Paint borderPaint;
    protected Paint cornerPaint;
    protected int maskColor;
    protected int laserColor;
    protected int scannerAlpha;
    protected CameraPreview cameraPreview;
    protected int cornerColor; //?
    protected int borderColor; //
    protected float borderWidth; //
    protected float cornerWidth; //?
    protected float cornerLength; //?
    private final long animationDelay = 5L;
    private float speed = 5;
    private int laserPadding = 10;

    protected Paint textPaint;

    int offset = 0;

    String statusText;

    float statusTextPadding = 32f;

    int statusTextColor = Color.parseColor("#b6b0b0");

    Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    int statusTextSize;

    // Cache the framingRect and previewFramingRect, so that we can still draw it after the preview
    // stopped.
    protected Rect framingRect;
    protected Rect previewFramingRect;

    // This constructor is used when the class is built from an XML resource.
    public WXViewfinderView(Context context, AttributeSet attrs) {
        super(context, attrs);

        // Initialize these once for performance rather than calling them every time in onDraw().
        maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        borderPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        cornerPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Resources resources = getResources();

        // Get setted attributes on view
        TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.zxing_WXViewfinderView);

        this.maskColor = attributes.getColor(R.styleable.zxing_WXViewfinderView_zxing_mask_color,
                Color.parseColor("#8c000000"));
        this.laserColor = attributes.getColor(R.styleable.zxing_WXViewfinderView_zxing_laser_color,
                Color.parseColor("#d90000"));
        this.cornerColor = attributes.getColor(R.styleable.zxing_WXViewfinderView_zxing_corner_color,
                Color.parseColor("#d90000"));
        this.borderColor = attributes.getColor(R.styleable.zxing_WXViewfinderView_zxing_border_color,
                Color.parseColor("#dfdfdf"));
        this.borderWidth = attributes.getDimension(R.styleable.zxing_WXViewfinderView_zxing_border_width, 1);
        this.cornerWidth = attributes.getDimension(R.styleable.zxing_WXViewfinderView_zxing_corner_width, 3);
        this.cornerLength = attributes.getDimension(R.styleable.zxing_WXViewfinderView_zxing_corner_length, 12);
        this.statusText = attributes.getString(R.styleable.zxing_WXViewfinderView_zxing_status_text);
        if (statusText == null) {
            statusText = "?????";
        }
        this.statusTextColor = attributes.getColor(R.styleable.zxing_WXViewfinderView_zxing_status_color,
                Color.parseColor("#b6b0b0"));
        this.statusTextPadding = attributes.getDimension(R.styleable.zxing_WXViewfinderView_zxing_status_padding,
                32);
        this.statusTextSize = attributes.getDimensionPixelSize(R.styleable.zxing_WXViewfinderView_zxing_status_size,
                24);
        maskPaint.setStyle(Paint.Style.FILL);
        maskPaint.setColor(maskColor);
        borderPaint.setStyle(Paint.Style.STROKE);
        borderPaint.setStrokeWidth(borderWidth);
        borderPaint.setColor(borderColor);
        cornerPaint.setStrokeWidth(cornerWidth);
        cornerPaint.setColor(cornerColor);
        cornerPaint.setStyle(Paint.Style.STROKE);
        textPaint.setTextSize(statusTextSize);
        textPaint.setColor(statusTextColor);
        attributes.recycle();
    }

    public void setCameraPreview(CameraPreview view) {
        this.cameraPreview = view;
        view.addStateListener(new CameraPreview.StateListener() {
            @Override
            public void previewSized() {
                refreshSizes();
                invalidate();
            }

            @Override
            public void previewStarted() {

            }

            @Override
            public void previewStopped() {

            }

            @Override
            public void cameraError(Exception error) {

            }
        });
    }

    protected void refreshSizes() {
        if (cameraPreview == null) {
            return;
        }
        Rect framingRect = cameraPreview.getFramingRect();
        Rect previewFramingRect = cameraPreview.getPreviewFramingRect();
        if (framingRect != null && previewFramingRect != null) {
            this.framingRect = framingRect;
            this.previewFramingRect = previewFramingRect;
        }
    }

    public void setStatusText(String statusText) {
        this.statusText = statusText;
        invalidate();
    }

    @SuppressLint("DrawAllocation")
    @Override
    public void onDraw(Canvas canvas) {
        refreshSizes();
        if (framingRect == null || previewFramingRect == null) {
            return;
        }

        Rect frame = framingRect;
        Rect previewFrame = previewFramingRect;

        int width = canvas.getWidth();
        int height = canvas.getHeight();

        maskPaint.setColor(maskColor);
        canvas.drawRect(0, 0, width, frame.top, maskPaint);
        canvas.drawRect(0, frame.top, frame.left, frame.bottom + 1, maskPaint);
        canvas.drawRect(frame.right + 1, frame.top, width, frame.bottom + 1, maskPaint);
        canvas.drawRect(0, frame.bottom + 1, width, height, maskPaint);
        //drawable the border
        canvas.drawRect(frame.left + 1, frame.top + 1, frame.right, frame.bottom, borderPaint);
        int halfWidth = (int) (cornerWidth / 2);
        //draw four corner
        Path corner1 = new Path();
        corner1.moveTo(frame.left, frame.top + cornerLength);
        corner1.lineTo(frame.left, frame.top);
        corner1.lineTo(frame.left + cornerLength, frame.top);
        Matrix translate1 = new Matrix();
        translate1.setTranslate(halfWidth, halfWidth);
        corner1.transform(translate1);
        canvas.drawPath(corner1, cornerPaint);

        Path corner2 = new Path();
        corner2.moveTo(frame.right + 1 - cornerLength, frame.top);
        corner2.lineTo(frame.right + 1, frame.top);
        corner2.lineTo(frame.right + 1, frame.top + cornerLength);
        Matrix translate2 = new Matrix();
        translate2.setTranslate(-halfWidth, halfWidth);
        corner2.transform(translate2);
        canvas.drawPath(corner2, cornerPaint);

        Path corner3 = new Path();
        corner3.moveTo(frame.left, frame.bottom + 1 - cornerLength);
        corner3.lineTo(frame.left, frame.bottom + 1);
        corner3.lineTo(frame.left + cornerLength, frame.bottom + 1);
        Matrix translate3 = new Matrix();
        translate3.setTranslate(halfWidth, -halfWidth);
        corner3.transform(translate3);
        canvas.drawPath(corner3, cornerPaint);

        Path corner4 = new Path();
        corner4.moveTo(frame.right + 1 - cornerLength, frame.bottom + 1);
        corner4.lineTo(frame.right + 1, frame.bottom + 1);
        corner4.lineTo(frame.right + 1, frame.bottom + 1 - cornerLength);
        Matrix translate4 = new Matrix();
        translate4.setTranslate(-halfWidth, -halfWidth);
        corner4.transform(translate4);
        canvas.drawPath(corner4, cornerPaint);

        offset += speed;
        if (offset >= frame.bottom - frame.top) {
            offset = 0;
        }
        Rect rect = new Rect();
        rect.left = frame.left + 1 + laserPadding;
        rect.top = frame.top + 1 + offset;
        rect.right = frame.right - laserPadding;
        rect.bottom = frame.top + 1 + offset + 3;

        Bitmap laserBitmap = ((BitmapDrawable) ResourcesCompat.getDrawable(getResources(), R.drawable.scan_laser,
                null)).getBitmap();
        canvas.drawBitmap(laserBitmap, null, rect, linePaint);

        textPaint.setTextAlign(Paint.Align.CENTER);

        canvas.drawText(statusText, (frame.right + frame.left) / 2,
                frame.bottom + statusTextPadding + statusTextSize, textPaint);

        postInvalidateDelayed(animationDelay, frame.left, frame.top, frame.right, frame.bottom);

    }

}