博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android开发——本地验证码的简易实现
阅读量:4045 次
发布时间:2019-05-24

本文共 3935 字,大约阅读时间需要 13 分钟。

0.  前言  

验证码无处不在,有人问我,你知道达芬奇密码下面是什么吗,对,答案就是达芬奇验证码。

验证码一个最主要的作用就是防止恶意暴力破解登录,防止不间断的登录尝试,其实可以在服务器端对该终端进行登录间隔检测,如果间隔太短可以展示拒绝的姿态。但是还是本地验证码作用更加实在,可以减轻服务器端的压力。这篇将使用自定义View来实现一个如下效果的简易本地验证码。算是对自定义View知识的复习吧。

1.  布局结构  

在自定义控件MyView中使用了自定义属性,面试的时候偶尔也会被问到,其实并不难。这里使用文字内容、颜色和字号三个自定义属性。命名空间别忘了加。

自定义属性声明只需要在values目录下声明一个xml文件即可。文件名字不重要,重要的是这个name属性,因为我们会在自定义控件类中通过R.styleable.MyView来找到这个自定义属性声明信息。

2.  自定义View

看一下这个类的构造函数:

public MyView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MyView);        for (int i = 0; i < a.getIndexCount(); i++) {            int attr = a.getIndex(i);            switch (attr) {                case R.styleable.MyView_text:                    mText = a.getString(attr);                    break;                case R.styleable.MyView_textcolor:                    //二参为默认颜色                    mTextColor = a.getColor(attr, Color.BLACK);                    break;                case R.styleable.MyView_textsize:                    // 默认字体大小为16sp,TypeValue把sp转化为px                    mTextSize = a.getDimensionPixelSize(attr,                            (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP,                                    16, getResources().getDisplayMetrics()));                    break;            }        }        a.recycle();        mPaint = new Paint();        mPaint.setTextSize(mTextSize);        mBound = new Rect();        //获得绘制文本的宽和高        mPaint.getTextBounds(mText, 0, mText.length(), mBound);        this.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                //生成一个随机的四位数字,并发送一个自定义广播                mText = randomText();                postInvalidate();            }        });    }

核心代码就是解析自定义属性,并初始化一个画笔,并把解析出来的字体大小设置给画笔,设计点击时间,使其被点击后重新随机产生四位数字验证码,并使用postInvalidate()刷新界面。最后使用mBound记录这个四位数文本的宽高。

 

2.  自定义View类中的其他细节

@Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        int width = 0;        int height = 0;        int specMode = MeasureSpec.getMode(widthMeasureSpec);        int specSize = MeasureSpec.getSize(widthMeasureSpec);        switch (specMode) {            case MeasureSpec.EXACTLY:                width = getPaddingLeft() + getPaddingRight() + specSize;                break;            case MeasureSpec.AT_MOST:                width = getPaddingLeft() + getPaddingRight() + mBound.width();                break;        }        //同样逻辑处理高        setMeasuredDimension(width, height);}    @Override    protected void onDraw(Canvas canvas) {        mPaint.setColor(Color.YELLOW);        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);        mPaint.setColor(mTextColor);        canvas.drawText(mText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mPaint);        Random random = new Random();        for(int i = 0; i <= 3; i++){            int temp = random.nextInt(colors.length);            mPaint.setColor(colors[temp]);            mPaint.setStrokeWidth(3);            canvas.drawLine(randomStartWidth(),randomStartHeight(),randomEndWidth(),randomEndHeight(),mPaint);        }    }

其实主要还是measuredraw的过程了。

onMeasure()方法中最重要的逻辑应该就是处理MeasureSpec.AT_MOST的这种情况了,这时候前面的mBound.width()就起作用了。还有就是不管何种测量模式,都手动处理了padding的情况。

onDraw()方法中首先绘制了一个黄色矩形作为自定义View的背景,接着根据自定义属性中的文字内容和颜色绘制四位数字,最后绘制四条噪声直线,颜色随机,并且起始位置和结束位置也是随机产生的。

 

3.  实时改变维护的正确验证码

为了验证用户输入的验证码的正确性,需要在MainActivity中维护一个变量,在用户点击自定义View刷新验证码时,能够实时改变这个变量的值。这里使用自定义广播实现,在生成一个随机的四位数字,发送一个自定义广播。

Intent intent = new Intent();intent.setAction("com.seu_calvin.update");intent.putExtra("data", sb.toString());getContext().sendBroadcast(intent);

接着在MainActivity注册一个广播接收者即可取得此时的验证码信息,在用户点击确定按钮后在拿到EditText中的值与其进行对比即可。这个逻辑还是比较简单的。

笔者水平有限,如果有问题或者错误请多留言交流。转载请注明出处:。

你可能感兴趣的文章
学习设计模式(3)——单例模式和类的成员函数中的静态变量的作用域
查看>>
自然计算时间复杂度杂谈
查看>>
当前主要目标和工作
查看>>
使用 Springboot 对 Kettle 进行调度开发
查看>>
一文看清HBase的使用场景
查看>>
解析zookeeper的工作流程
查看>>
搞定Java面试中的数据结构问题
查看>>
慢慢欣赏linux make uImage流程
查看>>
linux内核学习(7)脱胎换骨解压缩的内核
查看>>
以太网基础知识
查看>>
慢慢欣赏linux 内核模块引用
查看>>
kprobe学习
查看>>
慢慢欣赏linux phy驱动初始化2
查看>>
慢慢欣赏linux CPU占用率学习
查看>>
2020年终总结
查看>>
Homebrew指令集
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
React Native(二):属性、状态
查看>>
JSX使用总结
查看>>
React Native(四):布局(使用Flexbox)
查看>>