二维码扫描框样式修饰
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);
}
}
}
}}