|
目录
- 背景
- 横线效果
- 网格效果
- 基础属性
- 绘制背景色
- 绘制边框线
- 绘制四个边角线
- 扫描线绘制及移动
- 特点
背景
最近在开发新项目时,使用了扫描二维码的功能,一般扫描二维码的效果是一条横线从上到下循环移动,这次却换成了网格图片。网上的大多数第三方库实现类似效果时 网格图片被拉伸变形。为了实现效果,只能动手写,话不多说,先看效果。 (片尾附有代码地址)
横线效果
网格效果
基础属性
这里自定义了一些常见属性:
scan_image扫描图片资源scan_duration扫描一次时间 msscan_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分别绘制。
绘制边框线
- /**
- * 画边框线
- */
- 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)
复制代码代码简洁,不用区分是线性扫描还是网格扫描,都可以直接使用,使用时,只需传入需要的扫描图片即可。
项目地址:github.com/AndroidYou/ScanCodeView
以上就是Android自定义View实现两种二维码的扫描效果的详细内容,更多关于Android二维码扫描的资料请关注晓枫资讯其它相关文章!
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:  进行删除处理。
4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
|