博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
创建手势密码
阅读量:5082 次
发布时间:2019-06-13

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

设置手势密码,看大神弄的,我自己也跟着学了一遍,还是不太懂,但依然分享给大家

大家看代码吧!

1、mainactivity:

1 package com.wangy.wiperswitch; 2  3 import android.app.Instrumentation; 4 import android.content.Intent; 5 import android.content.SharedPreferences; 6 import android.support.v7.app.AppCompatActivity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.Button;10 import android.widget.Toast;11 12 public class MainActivity extends AppCompatActivity implements View.OnClickListener {13 14     private Button btn_gesture;15     private String password;16 17     @Override18     protected void onCreate(Bundle savedInstanceState) {19         super.onCreate(savedInstanceState);20         setContentView(R.layout.activity_main);21         init();22     }23     private  void init(){24         btn_gesture = (Button)findViewById(R.id.btn_gesture);25         btn_gesture.setOnClickListener(MainActivity.this);26 27     }28 29     @Override30     public void onClick(View v) {31         switch (v.getId()){32             case R.id.btn_gesture:{33                 Intent intent=new Intent(MainActivity.this,GestureSetingActivity.class);34                 startActivityForResult(intent,RESULT_OK);35 //                finish();36                 break;37             }38         }39     }40 41     @Override42     protected void onActivityResult(int requestCode, int resultCode, Intent data) {43         super.onActivityResult(requestCode, resultCode, data);44         if (requestCode==RESULT_OK){45             if (data!=null){46                 Bundle bundle = data.getExtras();47                 if (bundle!=null){48                     Boolean isOk=bundle.getBoolean("isOk");49                     if (isOk){50                         password = bundle.getString("password");51                     }else {52                         Toast.makeText(MainActivity.this,"您两次输入的手势密码不相同,设置失败!",Toast.LENGTH_SHORT).show();53                     }54                 }55             }56         }57     }58 }

mainactivi布局:

1 
2
6
11 12
21 22
23 24

2点击进入设置密码界面GestureSetingActivity

1 package com.wangy.wiperswitch; 2  3 import android.content.Context; 4 import android.content.Intent; 5 import android.gesture.Gesture; 6 import android.graphics.Bitmap; 7 import android.graphics.BitmapFactory; 8 import android.graphics.Canvas; 9 import android.graphics.Matrix;10 import android.graphics.Paint;11 import android.os.Bundle;12 import android.os.PersistableBundle;13 import android.support.v4.app.Fragment;14 import android.support.v7.app.AppCompatActivity;15 import android.util.AttributeSet;16 import android.view.Display;17 import android.view.MotionEvent;18 import android.view.View;19 import android.view.WindowManager;20 import android.widget.FrameLayout;21 import android.widget.Toast;22 23 import com.wangy.wiperswitch.Custom.Drawl;24 import com.wangy.wiperswitch.Custom.GestureView;25 import com.wangy.wiperswitch.R;26 import com.wangy.wiperswitch.utils.SharepreferenceUtil;27 28 /**29  * Created by xhb on 2016/9/13.30  */31 public class GestureSetingActivity extends AppCompatActivity {32 33     private FrameLayout boby_layout;34     private String pass;35     private GestureView content;36     private int time=0;37 38     @Override39     protected void onCreate(Bundle savedInstanceState) {40         super.onCreate(savedInstanceState);41         setContentView(R.layout.gesture_setting_layout);42         init();43     }44     protected void init(){45         pass = "";46         boby_layout = (FrameLayout)findViewById(R.id.body_layout);47         WindowManager m = getWindowManager();48         Display d = m.getDefaultDisplay();49         content = new GestureView(this, pass, d.getWidth(), new Drawl.GestureCallBack() {50             @Override51             public void checkedSuccess(String s) {52                 if (s.length()<3){53                     Toast.makeText(GestureSetingActivity.this,"手势密码最少是3个!",Toast.LENGTH_SHORT).show();54                 }else {55                     if (time==0){56                         Toast.makeText(GestureSetingActivity.this,"请再输入一次!",Toast.LENGTH_SHORT).show();57                         time++;58                         pass=s;//将第一次输入的密码与第二次输入的密码比较是否一致59                          }else {60                         if (pass.equals(s)){61                             Toast.makeText(GestureSetingActivity.this,"设置成功!手势密码为:"+s,Toast.LENGTH_SHORT).show();62                             Bundle bundle = new Bundle();63                             bundle.putBoolean("isOk",true);64                             bundle.putString("password", s);65                             Intent intent = new Intent();66                             intent.putExtras(bundle);67                             setResult(RESULT_OK, intent);68                             SharepreferenceUtil.setstring(GestureSetingActivity.this,"pass",s);69                             finish();70                         }else {71                             Bundle bundle = new Bundle();72                             bundle.putBoolean("isOk", false);73                             Intent intent = new Intent();74                             intent.putExtras(bundle);75                             setResult(RESULT_OK, intent);76                             finish();77                         }78                     }79                 }80             }81 82             @Override83             public void checkedFail() {84                 Toast.makeText(GestureSetingActivity.this,"校验失败!",Toast.LENGTH_SHORT).show();85             }86         });87 88         //设置手势解锁显示到哪个布局里面89         content.setParentView(boby_layout);90     }91 }

GestureSetingActivity布局

1 
2
6 7
14
15

3、2中设计到了一个非常重要的自定义控件GestureView,这是手势密码特别重要的view,接下来看代码吧!

1 package com.wangy.wiperswitch.Custom;  2   3 import android.content.Context;  4 import android.view.View;  5 import android.view.ViewGroup;  6 import android.widget.ImageView;  7   8 import com.wangy.wiperswitch.R;  9 import com.wangy.wiperswitch.utils.ScreenUtils; 10  11 import java.util.ArrayList; 12 import java.util.List; 13  14 /** 15  * Created by xhb on 2016/9/14. 16  */ 17 public class GestureView extends ViewGroup{ 18  19     private int baseNum = 6; 20  21     private int[] screenDispaly; 22  23     private int d; 24     /** 25      * 声明一个集合用来封装坐标集合 26      */ 27     private List
list; 28 private Context context; 29 private Drawl drawl; 30 31 /** 32 * 包含9个ImageView的容器,初始化 33 * @param context 34 * @param passWord 用户传入密码 35 * @param callBack 手势绘制完毕的回调 36 */ 37 public GestureView(Context context, String passWord, float width, Drawl.GestureCallBack callBack) { 38 super(context); 39 screenDispaly = ScreenUtils.getScreenDispaly(context); 40 d = screenDispaly[0]/3; 41 this.list = new ArrayList
(); 42 this.context = context; 43 // 添加9个图标 44 addChild(); 45 // 初始化一个可以画线的view 46 drawl = new Drawl(context, list,passWord,width,callBack); 47 } 48 49 private void addChild(){ 50 for (int i = 0; i < 9; i++) { 51 ImageView image = new ImageView(context); 52 image.setBackgroundResource(R.drawable.lock_pattern_node_normal); 53 this.addView(image); 54 55 // 第几行 56 int row = i / 3; 57 // 第几列 58 int col = i % 3; 59 60 // 定义点的每个属性 61 int leftX = col*d+d/baseNum; 62 int topY = row*d+d/baseNum; 63 int rightX = col*d+d-d/baseNum; 64 int bottomY = row*d+d-d/baseNum; 65 66 Point p = new Point(leftX, rightX, topY, bottomY, image,i+1); 67 68 this.list.add(p); 69 } 70 } 71 72 73 public void setParentView(ViewGroup parent){ 74 // 得到屏幕的宽度 75 int width = screenDispaly[0]; 76 LayoutParams layoutParams = new LayoutParams(width, width); 77 78 this.setLayoutParams(layoutParams); 79 drawl.setLayoutParams(layoutParams); 80 81 parent.addView(drawl); 82 parent.addView(this); 83 84 } 85 86 87 @Override 88 protected void onLayout(boolean changed, int l, int t, int r, int b) { 89 for (int i = 0; i < getChildCount(); i++) { 90 //第几行 91 int row = i/3; 92 //第几列 93 int col = i%3; 94 View v = getChildAt(i); 95 v.layout(col*d+d/baseNum, row*d+d/baseNum+50, col*d+d-d/baseNum, row*d+d-d/baseNum+50); 96 } 97 } 98 99 @Override100 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {101 super.onMeasure(widthMeasureSpec, heightMeasureSpec);102 for (int i = 0; i < getChildCount(); i++) {103 View v = getChildAt(i);104 v.measure(widthMeasureSpec, heightMeasureSpec);105 }106 }107 108 }

这里面也有个非常重要的Drawl(用来初始化一个可以画线的view),还有自定义笔Point

Drawl:

 

1 package com.wangy.wiperswitch.Custom;  2   3 /**  4  * Created by xhb on 2016/9/14.  5  */  6   7 import android.content.Context;  8 import android.graphics.Bitmap;  9 import android.graphics.Canvas; 10 import android.graphics.Color; 11 import android.graphics.Paint; 12 import android.graphics.PorterDuff; 13 import android.util.Pair; 14 import android.view.MotionEvent; 15 import android.view.View; 16  17 import java.util.ArrayList; 18 import java.util.List; 19  20 import android.content.Context; 21 import android.graphics.Bitmap; 22 import android.graphics.Canvas; 23 import android.graphics.Color; 24 import android.graphics.Paint; 25 import android.graphics.Paint.Style; 26 import android.graphics.PorterDuff; 27 import android.util.Pair; 28 import android.view.MotionEvent; 29 import android.view.View; 30  31 import com.wangy.wiperswitch.utils.StringUtils; 32  33 import java.util.ArrayList; 34 import java.util.List; 35  36  37 /** 38  * 39  * @author wangy 40  * 41  */ 42 public  class Drawl extends View { 43     private int mov_x;// 声明起点坐标 44     private int mov_y; 45     private Paint paint;// 声明画笔 46     private Canvas canvas;// 画布 47     private Bitmap bitmap;// 位图 48  49     private List
list;// 装有各个view坐标的集合 50 private List
> lineList;// 记录画过的线 51 52 /** 53 * 手指当前在哪个Point内 54 */ 55 private Point currentPoint; 56 /** 57 * 用户绘图的回调 58 */ 59 private GestureCallBack callBack; 60 61 /** 62 * 用户当前绘制的图形密码 63 */ 64 private StringBuilder passWordSb; 65 66 /** 67 * 用户传入的passWord 68 */ 69 private String passWord; 70 71 public Drawl(Context context, List
list, String passWord, float width, GestureCallBack callBack) { 72 super(context); 73 paint = new Paint(Paint.DITHER_FLAG);// 创建一个画笔 74 bitmap = Bitmap.createBitmap((int)width, 800, Bitmap.Config.ARGB_8888); // 设置位图的宽高 75 canvas = new Canvas(); 76 canvas.setBitmap(bitmap); 77 78 paint.setStyle(Paint.Style.STROKE);// 设置非填充 79 paint.setStrokeWidth(10);// 笔宽5像素 80 paint.setColor(Color.parseColor("#ffffff"));// 设置颜色 81 paint.setAntiAlias(true);// 不显示锯齿 82 83 this.list = list; 84 this.lineList = new ArrayList
>(); 85 this.callBack = callBack; 86 87 //初始化密码缓存 88 this.passWordSb = new StringBuilder(); 89 this.passWord = passWord; 90 } 91 92 // 画位图 93 @Override 94 protected void onDraw(Canvas canvas) { 95 // super.onDraw(canvas); 96 canvas.drawBitmap(bitmap, 0, 0, null); 97 } 98 99 // 触摸事件100 @Override101 public boolean onTouchEvent(MotionEvent event) {102 switch (event.getAction()) {103 case MotionEvent.ACTION_DOWN:104 105 mov_x = (int) event.getX();106 mov_y = (int) event.getY();107 108 // 判断当前点击的位置是处于哪个点之内109 currentPoint = getPointAt(mov_x, mov_y);110 if (currentPoint != null) {111 currentPoint.setHighLighted(true);112 passWordSb.append(currentPoint.getNum());113 }114 // canvas.drawPoint(mov_x, mov_y, paint);// 画点115 invalidate();116 break;117 case MotionEvent.ACTION_MOVE:118 clearScreenAndDrawList();119 120 // 得到当前移动位置是处于哪个点内121 Point pointAt = getPointAt((int) event.getX(), (int) event.getY());122 //代表当前用户手指处于点与点之前123 if(currentPoint==null && pointAt == null){124 return true;125 }else{ //代表用户的手指移动到了点上126 if(currentPoint == null){ //先判断当前的point是不是为null127 //如果为空,那么把手指移动到的点赋值给currentPoint128 currentPoint = pointAt;129 //把currentPoint这个点设置选中为true;130 currentPoint.setHighLighted(true);131 passWordSb.append(currentPoint.getNum());132 }133 }134 135 if (pointAt == null || currentPoint.equals(pointAt)136 || pointAt.isHighLighted()) {137 // 点击移动区域不在圆的区域 或者138 // 如果当前点击的点与当前移动到的点的位置相同139 // 那么以当前的点中心为起点,以手指移动位置为终点画线140 canvas.drawLine(currentPoint.getCenterX(),141 currentPoint.getCenterY()+50, event.getX(), event.getY()+50,142 paint);// 画线143 } else {144 // 如果当前点击的点与当前移动到的点的位置不同145 // 那么以前前点的中心为起点,以手移动到的点的位置画线146 canvas.drawLine(currentPoint.getCenterX(),147 currentPoint.getCenterY()+50, pointAt.getCenterX(),148 pointAt.getCenterY()+50, paint);// 画线149 150 pointAt.setHighLighted(true);151 152 Pair
pair = new Pair
(currentPoint,153 pointAt);154 lineList.add(pair);155 156 // 赋值当前的point;157 currentPoint = pointAt;158 passWordSb.append(currentPoint.getNum());159 }160 invalidate();161 break;162 case MotionEvent.ACTION_UP:// 当手指抬起的时候163 // 清掉屏幕上所有的线,只画上集合里面保存的线164 if(StringUtils.isEmpty(passWord)){165 callBack.checkedSuccess(passWordSb.toString());166 }else{167 if(passWord.equals(passWordSb.toString())){168 //代表用户绘制的密码手势与传入的密码相同169 callBack.checkedSuccess(passWordSb.toString());170 }else{171 //用户绘制的密码与传入的密码不同。172 callBack.checkedFail();173 }174 }175 176 //重置passWordSb177 passWordSb = new StringBuilder();178 //清空保存点的集合179 lineList.clear();180 //重新绘制界面181 clearScreenAndDrawList();182 for (Point p : list) {183 p.setHighLighted(false);184 }185 invalidate();186 break;187 default:188 break;189 }190 return true;191 }192 193 /**194 * 通过点的位置去集合里面查找这个点是包含在哪个Point里面的195 *196 * @param x197 * @param y198 * @return 如果没有找到,则返回null,代表用户当前移动的地方属于点与点之间199 */200 private Point getPointAt(int x, int y) {201 202 for (Point point : list) {203 // 先判断x204 int leftX = point.getLeftX();205 int rightX = point.getRightX();206 if (!(x >= leftX && x < rightX)) {207 // 如果为假,则跳到下一个对比208 continue;209 }210 211 int topY = point.getTopY();212 int bottomY = point.getBottomY();213 if (!(y >= topY && y < bottomY)) {214 // 如果为假,则跳到下一个对比215 continue;216 }217 218 // 如果执行到这,那么说明当前点击的点的位置在遍历到点的位置这个地方219 return point;220 }221 222 return null;223 }224 225 /**226 * 清掉屏幕上所有的线,然后画出集合里面的线227 */228 private void clearScreenAndDrawList() {229 canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);230 for (Pair
pair : lineList) {231 canvas.drawLine(pair.first.getCenterX(), pair.first.getCenterY()+50,232 pair.second.getCenterX(), pair.second.getCenterY()+50, paint);// 画线233 }234 }235 236 public interface GestureCallBack{237 238 /**239 * 代表用户绘制的密码与传入的密码相同240 */241 void checkedSuccess(String s);242 /**243 * 代表用户绘制的密码与传入的密码不相同244 */245 void checkedFail();246 }247 248 }

 

Point

1 package com.wangy.wiperswitch.Custom;  2   3 import android.widget.ImageView;  4   5 import com.wangy.wiperswitch.R;  6   7 /**  8  * Created by xhb on 2016/9/14.  9  */ 10     public class Point { 11         /** 12          * 左边x的值 13          */ 14         private int leftX; 15         /** 16          * 右边x的值 17          */ 18         private int rightX; 19         /** 20          * 上边y的值 21          */ 22         private int topY; 23         /** 24          * 下边y的值 25          */ 26         private int bottomY; 27         /** 28          * 这个点对应的ImageView控件 29          */ 30         private ImageView image; 31  32         /** 33          * 中心x值 34          */ 35         private int centerX; 36  37         /** 38          * 中心y值 39          */ 40         private int centerY; 41  42         /** 43          * 是否是高亮(划过) 44          */ 45         private boolean highLighted; 46  47         /** 48          * 代表这个Point对象代表的数字,从1开始(直接感觉从1开始) 49          */ 50         private int num; 51  52         public Point(int leftX, int rightX, int topY, int bottomY, ImageView image, int num) { 53             super(); 54             this.leftX = leftX; 55             this.rightX = rightX; 56             this.topY = topY; 57             this.bottomY = bottomY; 58             this.image = image; 59  60             this.centerX = (leftX + rightX) / 2; 61             this.centerY = (topY + bottomY) / 2; 62  63             this.num = num; 64         } 65  66         public int getLeftX() { 67             return leftX; 68         } 69  70         public void setLeftX(int leftX) { 71             this.leftX = leftX; 72         } 73  74         public int getRightX() { 75             return rightX; 76         } 77  78         public void setRightX(int rightX) { 79             this.rightX = rightX; 80         } 81  82         public int getTopY() { 83             return topY; 84         } 85  86         public void setTopY(int topY) { 87             this.topY = topY; 88         } 89  90         public int getBottomY() { 91             return bottomY; 92         } 93  94         public void setBottomY(int bottomY) { 95             this.bottomY = bottomY; 96         } 97  98         public ImageView getImage() { 99             return image;100         }101 102         public void setImage(ImageView image) {103             this.image = image;104         }105 106         public int getCenterX() {107             return centerX;108         }109 110         public void setCenterX(int centerX) {111             this.centerX = centerX;112         }113 114         public int getCenterY() {115             return centerY;116         }117 118         public void setCenterY(int centerY) {119             this.centerY = centerY;120         }121 122         public boolean isHighLighted() {123             return highLighted;124         }125 126         public void setHighLighted(boolean highLighted) {127             this.highLighted = highLighted;128             if (highLighted) {129                 this.image.setBackgroundResource(R.drawable.lock_pattern_node_pressed);130             } else {131                 this.image.setBackgroundResource(R.drawable.lock_pattern_node_normal);132             }133         }134 135         public int getNum() {136             return num;137         }138 139         public void setNum(int num) {140             this.num = num;141         }142 143         @Override144         public int hashCode() {145             final int prime = 31;146             int result = 1;147             result = prime * result + bottomY;148             result = prime * result + ((image == null) ? 0 : image.hashCode());149             result = prime * result + leftX;150             result = prime * result + rightX;151             result = prime * result + topY;152             return result;153         }154 155         @Override156         public boolean equals(Object obj) {157             if (this == obj)158                 return true;159             if (obj == null)160                 return false;161             if (getClass() != obj.getClass())162                 return false;163             Point other = (Point) obj;164             if (bottomY != other.bottomY)165                 return false;166             if (image == null) {167                 if (other.image != null)168                     return false;169             } else if (!image.equals(other.image))170                 return false;171             if (leftX != other.leftX)172                 return false;173             if (rightX != other.rightX)174                 return false;175             return topY == other.topY;176         }177 178         @Override179         public String toString() {180             return "Point [leftX=" + leftX + ", rightX=" + rightX + ", topY="181                     + topY + ", bottomY=" + bottomY + "]";182         }183     }

4、这就完成了,不过其中需要用到一些工具类我都奉上啦!

ScreenUtils:获取手机屏幕的高度和宽度
1 public class ScreenUtils { 2     @SuppressWarnings("deprecation") 3     public static int[] getScreenDispaly(Context context){ 4         WindowManager wm=(WindowManager)context.getSystemService(Context.WINDOW_SERVICE); 5         int width=wm.getDefaultDisplay().getWidth();//手机屏幕的宽度 6         int height=wm.getDefaultDisplay().getHeight();//手机屏幕的高度 7         int result[] = {width,height}; 8         return result; 9 10     }11 }
SharepreferenceUtil:本地记录密码,一般用于登录
1 package com.wangy.wiperswitch.utils; 2  3 import android.content.Context; 4 import android.content.SharedPreferences; 5  6 /** 7  * Created by xhb on 2016/9/18. 8  */ 9 public class SharepreferenceUtil {10         private static final String   name="cogi";11         public static  boolean getboolean(Context con,String key,boolean defaultValues){12             SharedPreferences sp=con.getSharedPreferences(name13                     ,Context.MODE_PRIVATE);14             return sp.getBoolean(key, defaultValues);15         }16 17         public static void putboolean(Context con,String key,boolean values){18             SharedPreferences sp=con.getSharedPreferences(name,Context.MODE_PRIVATE);19             sp.edit().putBoolean(key, values).commit();20         }21 22         public static  String getstring(Context con,String key,String defaultValues){23             SharedPreferences sp=con.getSharedPreferences(name24                     ,Context.MODE_PRIVATE);25             return sp.getString(key, defaultValues);26         }27 28         public static void setstring(Context con,String key,String values){29             SharedPreferences sp=con.getSharedPreferences(name,Context.MODE_PRIVATE);30             sp.edit().putString(key, values).commit();31         }32     }
StringUtils:字符串常用的
1 public class StringUtils { 2         public StringUtils() { 3         } 4  5         public static boolean isEmpty(String str) { 6             return str == null || str.length() == 0; 7         } 8  9         public static boolean equals(String str1, String str2) {10             return str1 == null?str2 == null:str1.equals(str2);11         }12 13         public static boolean equalsIgnoreCase(String str1, String str2) {14             return str1 == null?str2 == null:str1.equalsIgnoreCase(str2);15         }16 17         public static boolean gbk(String str) {18             int count = 0;19             String regEx = "[\\u4e00-\\u9fa5]";20             Pattern p = Pattern.compile(regEx);21             Matcher m = p.matcher(str);22 23             while(m.find()) {24                 for(int i = 0; i <= m.groupCount(); ++i) {25                     ++count;26                 }27             }28 29             if(count > 0) {30                 return true;31             } else {32                 return false;33             }34         }35

图片也打包送上了背景图就不放了,随大家了

看看效果图吧!

 

转载于:https://www.cnblogs.com/wangying222/p/6030389.html

你可能感兴趣的文章
实验五 Java网络编程及安全
查看>>
32位与64位 兼容编程
查看>>
iframe父子页面通信
查看>>
ambari 大数据安装利器
查看>>
java 上传图片压缩图片
查看>>
magento 自定义订单前缀或订单起始编号
查看>>
ACM_拼接数字
查看>>
计算机基础作业1
查看>>
Ubuntu 深度炼丹环境配置
查看>>
C#中集合ArrayList与Hashtable的使用
查看>>
从一个标准 url 里取出文件的扩展名
查看>>
map基本用法
查看>>
poj-1163 动态规划
查看>>
Golang之interface(多态,类型断言)
查看>>
Redis快速入门
查看>>
BootStrap---2.表格和按钮
查看>>
Linear Algebra lecture 2 note
查看>>
CRC计算模型
查看>>
Ajax之404,200等查询
查看>>
Aizu - 1378 Secret of Chocolate Poles (DP)
查看>>