欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android自定義View實(shí)現(xiàn)兩種二維碼的掃描效果

 更新時(shí)間:2024年01月17日 15:31:25   作者:IT小碼哥  
這篇文章主要為大家詳細(xì)介紹了Android如何自定義View實(shí)現(xiàn)兩種二維碼的掃描效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

背景

最近在開(kāi)發(fā)新項(xiàng)目時(shí),使用了掃描二維碼的功能,一般掃描二維碼的效果是一條橫線從上到下循環(huán)移動(dòng),這次卻換成了網(wǎng)格圖片。網(wǎng)上的大多數(shù)第三方庫(kù)實(shí)現(xiàn)類似效果時(shí) 網(wǎng)格圖片被拉伸變形。為了實(shí)現(xiàn)效果,只能動(dòng)手寫,話不多說(shuō),先看效果。(片尾附有代碼地址)

橫線效果

網(wǎng)格效果

基礎(chǔ)屬性

這里自定義了一些常見(jiàn)屬性:

scan_image掃描圖片資源
scan_duration掃描一次時(shí)間 ms
scan_width正方形掃描框?qū)挾?/td>
scan_bg_color除正方形掃描框之外的背景顏色
scan_rect_width正方形掃描框邊框?qū)挾?/td>
scan_rect_color正方形掃描框邊框顏色
scan_border_width掃描框四個(gè)邊角線的寬度
scan_border_length掃描框四個(gè)邊角線的長(zhǎng)度
scan_border_color掃描框四個(gè)邊角線的顏色

繪制背景色

首先定義正方形掃描框矩形的位置,這么默認(rèn)使用屏幕中心的位置

 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分別繪制。

繪制邊框線

/**
     * 畫邊框線
     */
    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) } }
    }

通過(guò)上面定義的掃描框矩形,繪制掃描框的邊框線。

繪制四個(gè)邊角線

四個(gè)邊角線為折線,使用自定義view中的path實(shí)現(xiàn)比較簡(jiǎn)單。

    /**
     * 畫四個(gè)角
     */
    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!!)
    }

掃描線繪制及移動(dòng)

繪制掃描線使用了canvas.drawBitmap 方法 ,通過(guò)裁剪顯示位置繪制掃描圖片。

  /**
     * 繪制掃描線
     */
    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())
    }

這里通過(guò)調(diào)用postInvalidateDelayed 不停延遲繪制圖片來(lái)實(shí)現(xiàn)掃描圖的移動(dòng)效果。

特點(diǎn)

像zxing 等三方庫(kù) 直接使用掃描圖片來(lái)繪制效果,由于掃描框是正方形,如果網(wǎng)格掃描圖是長(zhǎng)方形圖片,則會(huì)導(dǎo)致被拉伸為正方形顯示,圖片變形。為了解決網(wǎng)格圖的變形問(wèn)題,這里對(duì)圖片進(jìn)行縮放處理,避免變形。

 val scaleHeight = mScanWidth.toFloat() / mLineBitmap!!.width * mLineBitmap!!.height
        mLineBitmap =
            Bitmap.createScaledBitmap(mLineBitmap!!, mScanWidth, scaleHeight.toInt(), true)

代碼簡(jiǎn)潔,不用區(qū)分是線性掃描還是網(wǎng)格掃描,都可以直接使用,使用時(shí),只需傳入需要的掃描圖片即可。

項(xiàng)目地址:github.com/AndroidYou/ScanCodeView

以上就是Android自定義View實(shí)現(xiàn)兩種二維碼的掃描效果的詳細(xì)內(nèi)容,更多關(guān)于Android二維碼掃描的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論