二維碼掃描框樣式修飾


1.實現效果

 

 

 

 

 

2.代碼實現與分析

/**
* 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 final class ViewfinderView extends View {
//下面三個變量不用管,一般都是這個標准大小
private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
private static final long ANIMATION_DELAY = 10L;
private static final int OPAQUE = 0xFF;

GradientDrawable mDrawable; //支持使用漸變色來繪制圖形,通常可以用作Button或是背景圖形。
private final Paint paint;//畫布
private Bitmap resultBitmap;//掃描結果
private final int maskColor; //界面背景色1
private final int resultColor; //界面背景色2
private int laserFrameBoundColor ;//掃描框4角顏色
private int laserFrameCornerWidth;//掃描框4角寬
private int laserFrameCornerLength;//掃描框4角高
private int drawTextColor = Color.WHITE;//提示文字顏色
private boolean drawTextGravityBottom = true;//提示文字位置
private String drawText = "將二維碼/條形碼放入框內,即可自動掃描";//提示文字
private int drawTextSize;//提示文字大小
private int drawTextMargin;//提示文字與掃描邊框的距離
private final int resultPointColor;//掃描框點顏色

/**
* 中間滑動線的最頂端位置
*/
private int slideTop;

/**
* 中間滑動線的最底端位置
*/
private int slideBottom;
/**
* 中間那條線每次刷新移動的距離
*/
private static final int SPEEN_DISTANCE = 5;
boolean isFirst;
private Collection<ResultPoint> possibleResultPoints;
private Collection<ResultPoint> lastPossibleResultPoints;

/**
* 初始化定義的各變量(顏色,大小)
* @param context
* @param attrs
*/
public ViewfinderView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
Resources resources = getResources();
maskColor = resources.getColor(R.color.viewfinder_mask);
resultColor = resources.getColor(R.color.result_view);
resultPointColor = resources.getColor(R.color.possible_result_points);
laserFrameBoundColor=resources.getColor(R.color.laserFrameBoundColor);
laserFrameCornerLength=20;
laserFrameCornerWidth=20;
drawTextSize=50;
drawTextMargin=100;
possibleResultPoints = new HashSet<ResultPoint>(5);
}

@Override //canvas繪圖
public void onDraw(Canvas canvas) {
Rect frame = CameraManager.get().getFramingRect();//取掃描框
if (frame == null) {
return;
}
//設置掃描線的上下邊界為掃描框的上下邊界
if(!isFirst){
isFirst = true;
slideTop = frame.top;
slideBottom = frame.bottom;
}

/**
*掃描框,掃描線,提示文字等的修飾
*/
actionView(canvas,frame);

//只刷新掃描框的內容,其他地方不刷新
postInvalidateDelayed(ANIMATION_DELAY, frame.left, frame.top, frame.right, frame.bottom);
}

public void drawViewfinder() {
resultBitmap = null;
invalidate();
}

/**
* Draw a bitmap with the result points highlighted instead of the live scanning display.
* @param barcode An image of the decoded barcode.
*/
public void drawResultBitmap(Bitmap barcode) {
resultBitmap = barcode;
invalidate();
}

public void addPossibleResultPoint(ResultPoint point) {
possibleResultPoints.add(point);
}

/**
* 繪制掃描框邊框四角
* @param canvas
* @param frame
*/
public 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
*/
public 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);//添加文字
}

/**
* 繪制掃描框
*/
public void drawRect2(Canvas canvas, Rect frame){
canvas.drawRect(frame.left, frame.top, frame.right + 1, frame.top + 2, paint);
canvas.drawRect(frame.left, frame.top + 2, frame.left + 2, frame.bottom - 1, paint);
canvas.drawRect(frame.right - 1, frame.top, frame.right + 1, frame.bottom - 1, paint);
canvas.drawRect(frame.left, frame.bottom - 1, frame.right + 1, frame.bottom + 1, paint);
}

/**
* 繪制界面背景色
* @param canvas
* @param frame
*/
public void drawRect1(Canvas canvas, Rect frame){
int width = canvas.getWidth();
int height = canvas.getHeight();
paint.setColor(resultBitmap != null ? resultColor : maskColor);//設置背景色maskColor或resultColor
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);
}
/**
* //繪制中間的線,每次刷新界面,中間的線往下移動SPEEN_DISTANCE
* @param canvas
* @param frame
*/
public void lineMove(Canvas canvas, Rect frame){
slideTop += SPEEN_DISTANCE;
if(slideTop >= frame.bottom){
slideTop = frame.top;
}
Rect lineRect = new Rect();
lineRect.left = frame.left;
lineRect.right = frame.right;
lineRect.top = slideTop;
lineRect.bottom = slideTop + 18;
canvas.drawBitmap(((BitmapDrawable)(getResources().getDrawable(R.drawable.qrcode_scan_line))).getBitmap(), null, lineRect, paint);

}

/**
* 對各控件的修飾的實現
* @param canvas
* @param frame
*/
public void actionView(Canvas canvas,Rect frame){

if (resultBitmap != null) {
paint.setAlpha(OPAQUE);
canvas.drawBitmap(resultBitmap, frame.left, frame.top, paint);
} else {
//調用修飾方法
drawRect1(canvas, frame);//設置界面背景色
drawRect2(canvas, frame);//繪制矩形
drawFrameCorner(canvas, frame);//繪制掃描框4角
drawText(canvas,frame);//對文字的描繪
lineMove(canvas, frame);//掃描線移動

Collection<ResultPoint> currentPossible = possibleResultPoints;
Collection<ResultPoint> currentLast = lastPossibleResultPoints;
if (currentPossible.isEmpty()) {
lastPossibleResultPoints = null;
} else {
possibleResultPoints = new HashSet<ResultPoint>(5);
lastPossibleResultPoints = currentPossible;
paint.setAlpha(OPAQUE);
paint.setColor(resultPointColor);
for (ResultPoint point : currentPossible) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 6.0f, paint);
}
}
if (currentLast != null) {
paint.setAlpha(OPAQUE / 2);
paint.setColor(resultPointColor);
for (ResultPoint point : currentLast) {
canvas.drawCircle(frame.left + point.getX(), frame.top + point.getY(), 3.0f, paint);
}
}
}
}}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM