自定义view——仿京东手势解锁

早上看个bug,忘了吃饭,最后定位到ROM的问题,反馈了。忙完了是时候享受了,现在戴上耳机,写个清爽点的文章。虽然很简单,刷刷存在感也好啊,毕竟好久没写文章了。
先直接上效果吧。

京东金融手势解锁

如何使用呢?

(1)对象的获取并设置正确的密码

mUnLockView = (UnLockView) findViewById(R.id.unlockview);
    mUnLockView.setmRightPsw("14789");

(2)然后在当前Activity或者Fragment中实现 UnLockView.ResponseInput接口。例子如下:

 @Override
public void inputOK() {
    //TODO
    Toast.makeText(this, "密码正确", Toast.LENGTH_SHORT).show();
}

@Override
public void inputErr() {
    //TODO
    Toast.makeText(this, "密码错误", Toast.LENGTH_SHORT).show();
}

自定义view(viewgroup)的步骤就是下面这个样子,很官方呢。

图片来自网络

我们的主要工作在onMeasure()和onDraw()中。在onMeasure()中负责测量view的大小,在onDraw()中负责view的绘制。

观察效果为9个圆,在未点击时为灰色,在点击或者划过的时候将背景变为蓝色并画连线,在该圆外围画一个蓝色线条的大圆。确实很简单,但是在实际的过程中遇到了几个问题,分享一下。

1.对象的存储

static class Circle{

    private int x;//x坐标
    private int y;//y坐标
    private int innderRadius; //小圆半径
    private int outterRadius; //大圆半径
    private boolean isClicked; //是否点击
}

当某个圆被划过或者被点击的时候,将isClicked置为true。

2.线条的绘制

我用path存储用户手势的路径,从点击屏幕到手指抬起为止。在画圆与圆之间的线条时又有所不同,涉及到一个小知识点与大家分享下。那就是Path的lineTo与setLastPoint方法的区别。先看下使用lineTo的效果。

lineTo

因为onTouchEvent是个回调方法,会不停被系统回调,所以如果用lineTo这个方法的话,因为坐标不停地变会画出曲线来,这个时候我们就需要用另外一个方法setLastPoint,这个会改变上一次绘制的点的位置,所以会画出一条直线来。

3.如何判断输入是否正确

用一个StringBuilder对象保存用户的输入数据,当用户手指抬起来时对比输入的内容与正确的密码,并告知用户。那么如何采集用户的输入呢?我们在点击圆或者划过某个圆的时候将圆的下标采集。

4.将密码的判断结果反馈给用户

在UnLockView中有个接口ResponseInput,只需要在当前的Activity或者Fragment中实现该接口即可。

public interface ResponseInput{

    public void inputOK();
    public void inputErr();
}

看下核心的代码吧,发现要将一个东西说明白真的挺难的,读书人的事就不要多说了,大家直接看代码吧。

判断点击或者划过的是哪个圆

   public int getClickedIndex(float x,float y){

    for(int i=0;i<circles.length;i++){
        Circle cirlce = circles[i];
        if( x >= cirlce.x - cirlce.outterRadius
                && x <= cirlce.x + cirlce.outterRadius
                && y<= cirlce.y + cirlce.outterRadius
                && y >= cirlce.y - cirlce.outterRadius){
            return i;
        }
    }
    return -1;
}

这个里面最重要的就是事件的处理了,我们简单看看事件处理的代码吧。

public boolean onTouchEvent(MotionEvent event) {

    int action = event.getAction();
    switch(action){

        case MotionEvent.ACTION_DOWN:{
           
            int index = getClickedIndex(event.getX(),event.getY());
            if(index >= 0 && index <= circles.length){
                
                //采集用户输入
                gatherInput(index);
                mPath.moveTo(circles[index].x,circles[index].y);
                return true;
            }else{
                //TODO 第一次没触到任何块则提示

                return false;
            }

        }
        case MotionEvent.ACTION_MOVE:{
           
            float x = event.getX();
            float y = event.getY();
            int index = getClickedIndex(x,y);
            if(index >= 0 && index < circles.length){
                circles[index].isClicked = true;
                //采集用户输入
                gatherInput(index);

                //这个地方是为了解决第一次点击时画点击点与点(0,0)的bug
                if(getClickedIndex(mNextX,mNextY) >= 0){
                    mPath.lineTo(circles[index].x,circles[index].y);
                }else{
                    mPath.setLastPoint(circles[index].x,circles[index].y);
                }
                mNextX = circles[index].x;
                mNextY = circles[index].y;
            }else{
                mNextX = x;
                mNextY = y;
                mPath.setLastPoint(mNextX,mNextY);

            }

            invalidate();
            
        }break;
        case MotionEvent.ACTION_UP:{
            
            //TODO 判断密码是否正确
            if(isInputOK()){

                object.inputOK();
                
            }else{
                object.inputErr();
            }
            uninit();

        }break;
    }
    return super.onTouchEvent(event);
}

从代码可以看出来,在MotionEvent.ACTION_DOWN中,我们分别进行了处理,那是因为如果return true的话,之后的MotionEvent.ACTION_UP
与MotionEvent.ACTION_MOVE事件才会被捕获,如果返回false则不会被捕获。

还有其他一些模块简单介绍下,属于不重要的部分。

1. 采集用户的输入

gatherInput()

2. 判断输入是否正确

isInputOK()

3. circles初始化

init()

4. 画笔的初始化与设置

initResources(Context context)

3. circles反初始化(在MotionEvent.ACTION_UP时调用将circles的isClicked置为false,path清空,input数据清空)

uninit()。

代码在git@github.com:rainyandsunny/GestureUnLock.git,欢迎star与下载。

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

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,401评论 25 707
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,350评论 0 17
  • 一朝电话惊醒,半夜无法入眠; 思人生百态,念千丝万缕; 皆妄; 矣!
    过客丷阅读 166评论 0 0
  • 再见,大奶妹 2021年6月5日,天晴,我出来了!本来以为这是多么激动人心的一刻,现在感觉和以前每次休假没什么区别...
    Kevenskaf阅读 3,249评论 3 3
  • 总体框架搭建 识别背景图片功能 StartScene界面样式及功能扫描成功后跳出界面两个按钮,选择开始游戏或退出游...
    Jackpot_0213阅读 191评论 0 0