自定义view | 强大的密码输入框

作者:rokudol,链接:

http://blog.rokudol.cn/%E8%87%AA%E5%AE%9A%E4%B9%89view---%E5%BC%BA%E5%A4%A7%E7%9A%84%E5%AF%86%E7%A0%81%E8%BE%93%E5%85%A5%E6%A1%86.html,本文由作者授权发布。


我司之前有个需求,要求类似支付宝那样的密码支付,产品要求输入的当前字符需要是明文密码,1s后转换为圆点,原本想网上那么多密码输入框,肯定没问题,结果UI一出图就懵逼了,翻遍了各个角落,都找不到类似的密码输入框,没办法,自己写吧。


使用方法,在gradle中添加:compile ‘com.rokudoll:PswText:1.0.0’即可使用

当然绘制思路参照了其他大佬的思路,言归正传,先来看看效果图:




1需求分析



拿到效果图,再结合产品的要求,整理出以下要求:
1、类似EditText的password模式,输入密码时,输入的当前密码为明文,而之前的密码变为圆点,1s后当前密码也变为圆点
2、整体密码框为一个颜色,而已输入或当前输入密码位置的密码框为另一个颜色
3、有阴影



2实现流程



自定义view的流程就不再赘述了,不太清楚的可以去看看鸿洋和郭林的教程,先写好自定义属性,按照之前分析的结果以及自己的一点想法,为了更方便的使用,就有了以下的自定义属性,目前没有使用枚举,全部都是以boolean值来规定使用哪种模式,不过之后会换成枚举,那么先来看看有哪些自定义属性:


设置好自定义属性后,就开始实现这个自定义控件了!首先肯定是计算宽高


onMeasure

作为一个数学很差的人,计算这个的过程确实是比较糟心的。。直接看图吧



图中说明两处:


1、spacingWidth:为什么在宽度已知的情况下,spacingWidth = borderWidth / 4:
很简单,因为用边框的宽度除以4得到的大小刚好是能让我接受的大小,且在pswLength = 7、8、9、10的时候,宽度也比较合适,说白了就是一点点凑出来的。

2、borderWidth:为什么在宽度已知的情况下,borderWidth = (width 4) / ((5 pswLength) - 1),
这个其实很好理解,当宽度已知的时候,borderWidth = width / 6 - spacingWidth,即宽度除以6减去一个间隙的宽度就等于一个边框的宽度,而间隙的宽度 = borderWidth /4,那么我们换算成一个方程式来看看,就一目了然了,如果这个方程式还看不懂,那就去请教一下初中数学老师吧。。



来看看完整代码:



按这种算法绘制出的view,其实右边还多了一个spacingWidth的宽度,因为我们给每一个边框都减去了一个spacingWidth的宽度,所以会多出一个spacingWidth的宽度,不过并不影响,我们可以在onDraw里把每一个密码框往右移0.5个spacingWidth的宽度,这样左右都空出了一小段空隙,视觉效果上也好看一点,直接来看看onDraw。


onDraw


绘制pswLength数量个密码框


先说说思路,我们用for循环的方式,循环绘制出pswLength个密码框,用canvas.drawRoundRect绘制密码框,如果使用图片的话,就绘制图片,那么来看看canvas.drawRoundRect需要传递的参数:


drawRoundRect(RectF rect, float rx, float ry, Paint paint)


rect:RectF对象,边框的具体坐标
rx,ry:圆角x,y轴的半径
paint:画笔

那我们先来计算边框的具体坐标,来看看草稿:



没错,这草稿就是这么low,数学差。。就是这么心酸,不过已经可以看出规律,前面说过,我们是用for循环的方式循环绘制出各个密码框,那么总结一下:


top = 0 bottom = height left = i (borderWidth + spacingWidth) right  = borderWidth + i (borderWidth + spacingWidth)        = ((i + 1) borderWidth) + (i spacingWidth)


这样绘制出来的密码框,就像前面提过的,右边会多出一个spacingWidth,所以我们left和right的坐标需要再改进一下:


int left = (int) ( (i (borderWidth + spacingWidth)) + (0.5 spacingWidth));
int right = (int) (((i + 1) borderWidth) + (i spacingWidth) + (0.7 * spacingWidth));

有同学要问了,为毛right要乘以0.7而不是0.5,因为乘以0.5边框位置还是不对呀!微调一下,乘以0.7刚刚好。


到这里并没有结束,为啥?


因为说好的可以用图片来绘制边框,我们还没有实现这一步,不过也很简单,不需要重新计算坐标,直接贴该部分的完整代码:



只绘制明文密码模式


这个很简单,就不多做解释了



说明一点,为什么在textX最后要加0.5*spacingWidth,因为我们绘制密码框的时候就多增加了这么多的宽度,所以绘制文字也要做同样的操作,同理,绘制圆点时也是一样,后面不多做赘述


只绘制圆点模式



绘制输入密码时密码框变换样式:



输入密码时,输入的当前密码为明文,1s后变为圆点模式,即默认模式



可能有同学注意到,这里我们计算的圆点坐标跟之前计算的不一样,为什么呢?因为在这里,我们计算的圆点坐标分为两种情况:


1、输入密码时,已输入的密码变为圆点,那么我们的圆点坐标就应该是用(i - 1)的方式去计算,这样才能实现输入到第二个密码时,第一个密码变为圆点
2、输入密码时,延迟1s后当前明文密码变为圆点,那么圆点坐标就应该是(i + 1)的方式计算


延迟绘制圆点



以上就是全部的绘制逻辑,计算坐标这类似乎没什么好解释的,接下来就是自定义键盘,界面不需要我们自己再重新设计,用系统的就好,来看看代码


键盘



说明一下只处理数字那部分,为什么是keyCode - 7,我们点进源码看看



可以看出,我们用keyCode - 7就刚好等于输入的数字


最终效果:



3结语


以上就是该自定义view的全部说明,并未贴出全部的完整代码,如有需要可到
GitHub查看完整源码,如果喜欢或觉得该控件对你有帮助还请点个star,文中如有错误还请指出,谢谢


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,079评论 25 707
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,947评论 4 60