仿微信二维码扫描自定义view

最近一直在学习自定义view,写了很多例子,但是都是自己写着玩的,项目中还真没用到,这不最近项目中有个二维码扫描的功能,这个网上也很多,但是自己既然学了,自定义view,也想练习一下,就果断自己重新定义自己的二维码扫描view。看了微信的效果还不错,就完全按照微信的样式写了。效果图:

仿微信二维码扫描自定义view

不管怎么样也是锻炼自己的一次机会:

//画笔
Paint paint;
//颜色值
int transformDrak;
//扫描图片
Bitmap bitmap;
//设置向上的偏移量
int scWidth;
//屏幕宽高
int screenwidth;
int screenheight;
设置初始化参数

public ScView(Context context) {
   this(context,null);
}
public ScView(Context context, @Nullable AttributeSet attrs) {
    this(context,attrs,0);
}
private Bitmap resultBitmap;
public ScView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    Resources resources = getResources();
    //这是根据屏幕分辨率获取的
    scWidth = Utils.dp2px(context,80);
    //屏幕宽度
    WindowManager wm = (WindowManager) getContext()
            .getSystemService(Context.WINDOW_SERVICE);
    screenwidth = wm.getDefaultDisplay().getWidth();
    screenheight = wm.getDefaultDisplay().getHeight();
    //颜色
    transformDrak = resources.getColor(R.color.result_view);
    //画笔
    paint = new Paint();
    paint.setDither(true);
    paint.setAntiAlias(true);
    //获取扫描线的图片
    bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.scan_light);
}
设置绘画方法

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    paint.setStyle(Paint.Style.FILL_AND_STROKE);
    paint.setStrokeWidth(1);
    /**
     * 绘制扫描区域,这里只是定义一个中间的那个正方形,
     * getRect() - 返回正方形的参数
     * screenwidth  屏幕宽度,
     * screenheight 屏幕高度
     */
    RectF rect = CameraManager.get().getRect(scWidth,screenwidth,screenheight);
    paint.setColor(Color.parseColor("#00000000"));
    canvas.drawRect(rect,paint);
    /**
     * 绘制扫描区域 以外的 区域 ---上部的区域
     */
    RectF top = new RectF(0,0,screenwidth,rect.top);
    paint.setColor(transformDrak);
    canvas.drawRect(top,paint);
    /**
     * 绘制扫描区域左侧的区域
     */
    RectF left = new RectF(0,rect.top,rect.left,rect.bottom);
    canvas.drawRect(left,paint);
    /**
     * 绘制扫描区域下方的区域
     */
    RectF bottom = new RectF(0,rect.bottom,screenwidth,screenheight);
    canvas.drawRect(bottom,paint);
    /**
     * 绘制扫描区域右侧的区域
     */
    RectF right = new RectF(rect.right,rect.top,screenwidth,rect.bottom);
    canvas.drawRect(right,paint);

    //绘制四角的宽线
    strokeLine(rect,canvas);

    //扫描线的绘制
    saoLine(rect,canvas);
}
下面是设置各个角的线

/**
 * 各个角的 绿色短粗线
 * @param rect
 * @param canvas
 */
public void strokeLine(RectF rect,Canvas canvas){
    paint.setColor(Color.parseColor("#c000ff00"));
    paint.setStrokeWidth(10);
    //左上角
    canvas.drawLine(rect.left,rect.top+5,rect.left+40,rect.top+5,paint);
    canvas.drawLine(rect.left+5,rect.top,rect.left+5,rect.top+40,paint);
    //右上角
    canvas.drawLine(rect.right,rect.top+5,rect.right-40,rect.top+5,paint);
    canvas.drawLine(rect.right-5,rect.top,rect.right-5,rect.top+40,paint);
    //左下角
    canvas.drawLine(rect.left,rect.bottom-5,rect.left+40,rect.bottom-5,paint);
    canvas.drawLine(rect.left+5,rect.bottom,rect.left+5,rect.bottom-40,paint);
    //右下角
    canvas.drawLine(rect.right,rect.bottom-5,rect.right-40,rect.bottom-5,paint);
    canvas.drawLine(rect.right-5,rect.bottom,rect.right-5,rect.bottom-40,paint);
}

//这是线上下移动 的变化坐标
int x ;

/**扫描线的绘制
 * @param rect
 * @param canvas
 */
public void saoLine(RectF rect,Canvas canvas){

    //绘制图片
    RectF line = new RectF(rect.left,rect.top+x,rect.right,rect.top+20+x);
    canvas.drawBitmap(bitmap,null,line,paint);
    //每次移动的高度
    x +=2;
    if (x>=rect.height()-10){
        x =0;
    }
    //重回
    postInvalidate();
}
设置中间矩形的参数

public RectF getRect (int scWidth,int screenwidth,int screenheight){
  RectF preFect;

  float coderWidth = (float) (screenwidth * 0.6);
  //距离左侧边的距离
  float offsetLeft = (screenwidth - coderWidth)/2;
  //距离顶部的距离
  float offsetTop = (screenheight - coderWidth)/2 - scWidth/3;

  preFect = new RectF(offsetLeft,offsetTop,offsetLeft+coderWidth,offsetTop+coderWidth);

  return preFect;
}
这是一个插曲,接下来我会接着上一篇的自定义view动画篇来写。。