android自定义view实现两种二维码的扫描效果-kb88凯时官网登录

来自:网络
时间:2024-06-09
阅读:
免费资源网,https://freexyz.cn/

背景

最近在开发新项目时,使用了扫描二维码的功能,一般扫描二维码的效果是一条横线从上到下循环移动,这次却换成了网格图片。网上的大多数第三方库实现类似效果时 网格图片被拉伸变形。为了实现效果,只能动手写,话不多说,先看效果。(片尾附有代码地址)

横线效果

android自定义view实现两种二维码的扫描效果

网格效果

android自定义view实现两种二维码的扫描效果

基础属性

这里自定义了一些常见属性:

scan_image扫描图片资源
scan_duration扫描一次时间 ms
scan_width正方形扫描框宽度
scan_bg_color除正方形扫描框之外的背景颜色
scan_rect_width正方形扫描框边框宽度
scan_rect_color正方形扫描框边框颜色
scan_border_width扫描框四个边角线的宽度
scan_border_length扫描框四个边角线的长度
scan_border_color扫描框四个边角线的颜色

绘制背景色

首先定义正方形扫描框矩形的位置,这么默认使用屏幕中心的位置

 private fun createrect() {
        val leftoffset = (width - mscanwidth) / 2f
        val topoffset = (height - mscanwidth) / 2f
        mrectframerect =
            rectf(leftoffset, topoffset, leftoffset   mscanwidth, topoffset   mscanwidth)
        val scaleheight = mscanwidth.tofloat() / mlinebitmap!!.width * mlinebitmap!!.height
        mlinebitmap =
            bitmap.createscaledbitmap(mlinebitmap!!, mscanwidth, scaleheight.toint(), true)
    }

绘制背景色

/**
     * 绘制背景色
     */
    private fun drawscanbackground(canvas: canvas?) {
        mpaint?.style = paint.style.fill
        mpaint?.color = mbackgroundcolor
        val canvaswidth = canvas?.width
        val canvasheight = canvas?.height
        mpaint?.let {
            canvas?.drawrect(0f, 0f, canvaswidth!!.tofloat(), mrectframerect!!.top, it)
            canvas?.drawrect(
                0f,
                mrectframerect!!.top - mborderwidth / 2,
                mrectframerect!!.left,
                mrectframerect!!.bottom   mborderwidth / 2,
                it
            )
            canvas?.drawrect(
                mrectframerect!!.right,
                mrectframerect!!.top - mborderwidth / 2,
                canvaswidth!!.tofloat(),
                mrectframerect!!.bottom,
                it
            )
            canvas?.drawrect(
                0f,
                mrectframerect!!.bottom - mborderwidth / 2,
                canvaswidth!!.tofloat(),
                canvasheight!!.tofloat(),
                it
            )
        }
    }

将阴影部分分为四块,使用canvas.drawrect分别绘制。

android自定义view实现两种二维码的扫描效果

绘制边框线

/**
     * 画边框线
     */
    private fun drawborderline(canvas: canvas?) {
        mpaint?.color = mrectcolor
        mpaint?.style = paint.style.stroke
        mpaint?.strokewidth = mrectwidth.tofloat()
        mrectframerect?.let { mpaint?.let { it1 -> canvas?.drawrect(it, it1) } }
    }

通过上面定义的扫描框矩形,绘制扫描框的边框线。

绘制四个边角线

四个边角线为折线,使用自定义view中的path实现比较简单。

    /**
     * 画四个角
     */
    private fun drawbordercorner(canvas: canvas?) {
        mpaint?.color = mbordercolor
        mpaint?.style = paint.style.stroke
        val connerwidth = mborderwidth / 2
        mpaint?.strokewidth = mborderwidth.tofloat()
        mpath.reset()
        //左上     
        mpath.moveto(mrectframerect!!.left, mrectframerect!!.top - connerwidth   mborderlength)
        mpath.lineto(mrectframerect!!.left, mrectframerect!!.top)
        mpath.lineto(mrectframerect!!.left - connerwidth   mborderlength, mrectframerect!!.top)
         //右上     
        mpath.moveto(mrectframerect!!.right   connerwidth - mborderlength, mrectframerect!!.top)
        mpath.lineto(mrectframerect!!.right, mrectframerect!!.top)
        mpath.lineto(mrectframerect!!.right, mrectframerect!!.top - mborderwidth   mborderlength)
        //左下    
        mpath.moveto(mrectframerect!!.left, mrectframerect!!.bottom   mborderwidth - mborderlength)
        mpath.lineto(mrectframerect!!.left, mrectframerect!!.bottom)
        mpath.lineto(mrectframerect!!.left - mborderwidth   mborderlength, mrectframerect!!.bottom)
         //右下 
        mpath.moveto(mrectframerect!!.right, mrectframerect!!.bottom   mborderwidth - mborderlength)
        mpath.lineto(mrectframerect!!.right, mrectframerect!!.bottom)
        mpath.lineto(mrectframerect!!.right   mborderwidth - mborderlength, mrectframerect!!.bottom)
        canvas?.drawpath(mpath, mpaint!!)
    }

扫描线绘制及移动

绘制扫描线使用了canvas.drawbitmap 方法 ,通过裁剪显示位置绘制扫描图片。

  /**
     * 绘制扫描线
     */
    private fun drawscanline(canvas: canvas?) {
        canvas?.save()
        canvas?.restore()
        val dstgridrectf = rectf(
            mrectframerect!!.left,
            mrectframerect!!.top,
            mrectframerect!!.right,
            mrectframerect!!.top   mmovestep
        )
        val srcrect = rect(
            0,
            (mlinebitmap!!.height - dstgridrectf.height()).toint(),
            mlinebitmap!!.width,
            mlinebitmap!!.height
        )
        mlinebitmap?.let {
            canvas?.drawbitmap(it, srcrect, dstgridrectf, mpaint)
        }
        mmovestep  = dp2px(3f)
        if (mmovestep >= mscanwidth   mlinebitmap!!.height / 2) {
            mmovestep = 0f
        }
        postinvalidatedelayed(mdelaytimes.tolong())
    }

这里通过调用postinvalidatedelayed 不停延迟绘制图片来实现扫描图的移动效果。

特点

像zxing 等三方库 直接使用扫描图片来绘制效果,由于扫描框是正方形,如果网格扫描图是长方形图片,则会导致被拉伸为正方形显示,图片变形。为了解决网格图的变形问题,这里对图片进行缩放处理,避免变形。

 val scaleheight = mscanwidth.tofloat() / mlinebitmap!!.width * mlinebitmap!!.height
        mlinebitmap =
            bitmap.createscaledbitmap(mlinebitmap!!, mscanwidth, scaleheight.toint(), true)

代码简洁,不用区分是线性扫描还是网格扫描,都可以直接使用,使用时,只需传入需要的扫描图片即可。

项目地址:

以上就是android自定义view实现两种二维码的扫描效果的详细内容,更多关于android二维码扫描的资料请关注其它相关文章!

免费资源网,https://freexyz.cn/
返回顶部
顶部
网站地图