Android 自定义控件实现手势密码

国际惯例:放上效果图(求人气啊,每次文章都石沉大海)


     首先呢想写这个手势密码的想法呢,完全是凭空而来的,然后笔者就花了一天时间弄出来了。本以为这个东西很简单,实际上手的时候发现,还有很多逻辑需要处理,稍不注意就容易乱套。写个UI效果图大约只花了3个小时,但是处理逻辑就处理了2个小时!废话不多说,下面开始讲解。

    楼主呢,自己比较自定义控件,什么东西都掌握在自己的手里感觉那是相当不错(对于赶工期的小伙瓣儿们还是别手贱了,非常容易掉坑),一有了这个目标,我就开始构思实现方式。

    1、整个自定义控件是继承View还是SurfaceView呢?我的经验告诉我:需要一直不断绘制的最好继承SurfaceView,而需要频繁与用户交互的最好就继承View。(求大神来打脸)

    2、为了实现控件的屏幕适配性,当然必须重写onMeasure方法,然后在onDraw方法中进行绘制。

    3、面向对象性:这个控件其实由两个对象组成:1、9个圆球;2、圆球之间的连线。

    4、仔细观察圆球的特征:普通状态是白色、touch状态是蓝色、错误状态是红色、整体分为外围空心圆和内实心圆、所代表的位置信息(密码值)

    5、仔细观察连线的特征:普通状态为蓝色、错误状态为红色、始终连接两个圆的中心、跟随手指移动而拓展连线、连线之间未点亮的圆球也要点亮。

    6、通过外露参数来设置圆球的颜色、大小等等

    7、通过上面的分析,真个控件可模块化为三个任务:onMeasure计算控件宽高以及小球半径、onDraw绘制小球与连线、onTouchEvent控制绘制变化。


    我把整个源码分为三个类文件:LockView、Circle、Util,其中LockView代表整个控件,Circle代表小圆球、Util封装工具方法(Path因为太简单就没封装,若有代码洁癖请自行封装),下面展示Util类的源代码。

public class Util{
    
    private static final String SP_NAME = "LOCKVIEW";
    private static final String SP_KEY = "PASSWORD";

    public static void savePwd(Context mContext ,List<Integer> password){
        SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
        sp.edit().putString(SP_KEY, listToString(password)).commit();
    }
    
    public static String getPwd(Context mContext){
        SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
        return sp.getString(SP_KEY, "");
    }
    
    public static void clearPwd(Context mContext){
        SharedPreferences sp = mContext.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE);
        sp.edit().remove(SP_KEY).commit();
    }
    
    public static String listToString(List<Integer> lists){
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < lists.size(); i++){
            sb.append(lists.get(i));
        }
        return sb.toString();
    }
    
    public static List<Integer> stringToList(String string){
        List<Integer> lists = new ArrayList<>();
        for(int i = 0; i < string.length(); i++){
            lists.add(Integer.parseInt(string.charAt(i) + ""));
        }
        return lists;
    }
}

    这个工具方法其实很简单,就是对SharedPreferences的一个读写,还有就是List与String类型的互相转换。这里就不描述了。下面展示Circle的源码

public class Circle{
    //默认值
    public static final int DEFAULT_COLOR = Color.WHITE;
    public static final int DEFAULT_BOUND = 5;
    public static final int DEFAULT_CENTER_BOUND = 15;
    //状态值
    public static final int STATUS_DEFAULT = 0;
    public static final int STATUS_TOUCH = 1;
    public static final int STATUS_SUCCESS = 2;
    public static final int STATUS_FAILED = 3;
    
    //圆形的中点X、Y坐标
    private int centerX;
    private int centerY;
    //圆形的颜色值
    private int colorDefault = DEFAULT_COLOR;
    private int colorSuccess;
    private int colorFailed;
    //圆形的宽度
    private int bound = DEFAULT_BOUND;
    //中心的宽度
    private int centerBound = DEFAULT_CENTER_BOUND;
    //圆形的半径
    private int radius;
    //圆形的状态
    private int status = STATUS_DEFAULT;
    //圆形的位置
    private int position;
    
    public Circle(int centerX, int centerY, int colorSuccess, int colorFailed, int radius, int position){
        super();
        this.centerX = centerX;
        this.centerY = centerY;
        this.colorSuccess = colorSuccess;
        this.colorFailed = colorFailed;
        this.radius = radius;
        this.position = position;
    }

    public Circle(int centerX, int centerY, int colorDefault, int colorSuccess, int colorFailed, int bound,
            int centerBound, int radius, int status, int position){
        super();
        this.centerX = centerX;
        this.centerY = centerY;
        this.colorDefault = colorDefault;
        this.colorSuccess = colorSuccess;
        this.colorFailed = colorFailed;
        this.bound = bound;
        this.centerBound = centerBound;
        this.radius = radius;
        this.status = status;
        this.position = position;
    }

    public int getCenterX(){
        return centerX;
    }

    public void setCenterX(int centerX){
        this.centerX = centerX;
    }

    public int getCenterY(){
        return centerY;
    }

    public void setCenterY(int centerY){
        this.centerY = centerY;
    }

    public int getColorDefault(){
        return colorDefault;
    }

    public void setColorDefault(int colorDefault){
        this.colorDefault = colorDefault;
    }

    public int getColorSuccess(){
        return colorSuccess;
    }

    public void setColorSuccess(int colorSuccess){
        this.colorSuccess = colorSuccess;
    }

    public int getColorFailed(){
        return colorFailed;
    }

    public void setColorFailed(int colorFailed){
        this.colorFailed = colorFailed;
    }

    public int getBound(){
        return bound;
    }

    public void setBound(int bound){
        this.bound = bound;
    }

    public int getCenterBound(){
        return centerBound;
    }

    public void setCenterBound(int centerBound){
        this.centerBound = centerBound;
    }

    public int getRadius(){
        return radius;
    }

    public void setRadius(int radius){
        this.radius = radius;
    }

    public int getStatus(){
        return status;
    }

    public void setStatus(int status){
        this.status = status;
    }

    public int getPosition(){
        return position;
    }

    public void setPosition(int position){
        this.position = position;
    }

    /**   
     * @Description:改变圆球当前状态  
    */
    public void changeStatus(int status){
        this.status = status;
    }
    
    /**   
     * @Description:绘制这个圆形  
    */
    public void draw(Canvas canvas ,Paint paint){
        switch(status){
            case STATUS_DEFAULT:
                paint.setColor(colorDefault);
                break;
            case STATUS_TOUCH:
            case STATUS_SUCCESS:
                paint.setColor(colorSuccess);
                break;
            case STATUS_FAILED:
                paint.setColor(colorFailed);
                break;
            default:
                paint.setColor(colorDefault);
                break;
        }
        paint.setStyle(Paint.Style.FILL);
        //绘制中心实心圆
        canvas.drawCircle(
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值