Android-自定义View实现二维码网格扫描+纵向雷达的扫描效果

本文介绍了如何在Android中自定义一个ScanView,通过继承View并利用Path、Shader来实现二维码网格扫描效果和纵向雷达扫描动画。首先创建静态的网格效果,然后使用LinearGradient着色器结合动画更新矩阵来实现扫描动画,从而达到视觉上的扫描动态效果。
摘要由CSDN通过智能技术生成

Android-自定义View实现二维码网格扫描+纵向雷达的扫描效果

最终效果如图:

这里写图片描述

1.可以看到整体是一个网格+纵向雷达扫描效果,因此首先我们先画出如下的静态效果,如下图

这里写图片描述

2.新建个View命名为ScanView 继承自View,并且在onLayout中初始化扫描区域为该组件中间的一块正方形
    @Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
    super.onLayout(changed, left, top, right, bottom);
    int measuredHeight = this.getMeasuredHeight();
    int measuredWidth = this.getMeasuredWidth();
    int rectHeight = 5 * measuredHeight / 8;
    int rectWidth = 5 * measuredWidth / 8;
    int rectLen = rectHeight>rectWidth?rectWidth:rectHeight;
    int rectLeft = (measuredWidth - rectLen) / 2;
    int rectTop = (measuredHeight - rectLen) / 2;
    mFrame = new Rect(rectLeft,rectTop,rectLeft+rectLen,rectTop+rectLen);//初始化扫描区域所在的Rect
    initBoundaryAndAnimator();//初始化动画效果及边框样式
}
3.根据扫描区域的Reat绘制四个顶点的角线,此处我们使用path绘制先构建出定点角线的路径如下,初始化动画的处理可先不管
private void initBoundaryAndAnimator() {
    if (mBoundaryLinePath == null) {
        mCornerLineLen = mFrame.width() * mCornerLineLenRatio;//mCornerLineLenRatio 是定点处线的长度站边长的比例
        mBoundaryLinePath = new Path();//初始化Path
        mBoundaryLinePath.moveTo(mFrame.left, mFrame.top + mCornerLineLen);//添加要绘制线的path到路径上
        mBoundaryLinePath.lineTo(mFrame.left, mFrame.top);
        mBoundaryLinePath.lineTo(mFrame.left + mCornerLineLen, mFrame.top);
        mBoundaryLinePath.moveTo(mFrame.right - mCornerLineLen, mFrame.top);
        mBoundaryLinePath.lineTo(mFrame.right, mFrame.top);
        mBoundaryLinePath.lineTo(mFrame.right, mFrame.top + mCornerLineLen);
        mBoundaryLinePath.moveTo(mFrame.right, mFrame.bottom - mCornerLineLen);
        mBoundaryLinePath.lineTo(mFrame.right, mFrame.bottom);
        mBoundaryLinePath.lineTo(mFrame.right - mCornerLineLen, mFrame.bottom);
        mBoundaryLinePath.moveTo(mFrame.left + mCornerLineLen, mFrame.bottom);
        mBoundaryLinePath.lineTo(mFrame.left, mFrame.bottom);
        mBoundaryLinePath.lineTo(mFrame.left, mFrame.bottom - mCornerLineLen);
    }

    if (mValueAnimator == null) {
        initScanValueAnim(mFrame.height());//初始化动画效果
    }
}
4.然后初始化网格的路径如下,要想使绘制出来的效果是渐变的则需要在初始化画笔时添加一个Shader(着色器),此处我们需要的是一个线性渐变的效果所以我们初始化一个LinearGradient的着色器。

ps:LinearGradient 的使用比较简单,但此处我们需要注意一下我们构建时使用的模式是 LinearGradient.TileMode.CLAMP,即当着色器的不能填满所要绘制的区域时的模式为拉伸最后一个像素。而此处我们最后的0.99f-1f区域设置的是Color.TRANSPARENT,所以当填不满时会拉伸透明像素,相当于图像截取到此处,这是后面动画效果实现的关键

    mScanPaint_Gridding = new Paint(Paint.ANTI_ALIAS_FLAG);
    mScanPaint_Gridding.setStyle(Paint.Style.STROKE);//设置Style为STROKE
    mScanPaint_Gridding.setStrokeWidth(mGriddingLineWidth);//设置线宽

    //初始化网格路径,及绘制该忘咯时所需要的画笔
    private void initGriddingPathAndStyle() {
    if (mGriddingPath == null) {//初始化路径
        mGriddingPath = new Path();
        float wUnit 
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值