基本上很多应用都有一个手势密码锁.估计很多大神可能会觉得这个东西很简单,就是九个点连接起来,然后保存在本地,当然如果你要加密的话用MD5或者HASH来加密一下,然后就来一个锁,锁代表安全,代表个人专属,代表身份象征哈,有钱淫都有锁,穷人没的锁哈..好了,不扯淡了..接下来咱们来搞一下这个东西

思路:
以3 * 3 的正方形手势密码绘制为例

先要想办法得到这个手势密码的九个点的坐标,然后进行绘制,并且以状态来改变此九个点的状态是按下还是普通,以及错误.最后将密码保存在本地,然后在测试的时候进行比对判断.大致思路如此,咱们还是上代码一步步走吧,毕竟步子走的大了容易扯到蛋..

首先: 首先个毛线啊,让我缕缕思路哈..我觉得要不先来个图吧..

这里在下粗略的画了一个图,毕竟是只猿,艺术么,和咱关系不大,玩不来那东西,于是乎就画了个比较丑的图,咋样才能得到这九个点的坐标呢,咱们要不这样吧..以手机屏幕的宽度为边长,在屏幕中心画一个四方块,然后把这个四方块呢在画成16个小方格子,如上图哈…然后得到每个小方格子的右下角的坐标就可以得到圆心的坐标系了哈..

那么好,接下来咱们来搞一下这个玩意儿.

首先,咱们要得到这九个点的坐标,咱先来个实体类来记录这些坐标的值.那咱就来个Point类.

package text.scc.com.scclock;/*** Created by scc on 2016/11/18.*/
public class Point {/*** 咱在这里定义三个常量来表示是普通呢还是按下呢还是错误呢的常量状态*/public static int STATE_NORMAL = 0;public static int STATE_PRESS = 1;public static int STATE_ERROR = 2;/*** 咱再在这里定义点的坐标系的值为x和y,通过底下的此类的构造方法来* 传进来x和y的值*/public float x;public float y;/*** 咱上面定义了三种状态的常量,咱再来个变量state来记录当下的状态* 默认为普通状态*/int state = STATE_NORMAL;/*** 这是此类构造方法,就不说啥了吧\(^o^)/~* @param x* @param y*/public Point(float x, float y) {this.x = x;this.y = y;}/*** 这个方法呢后面会用到,是用来监测用户按下屏幕的时候* 的坐标点在不在咱们的密码点的距离范围之内.后面咱在说哈* @param a* @return*/public float distance(Point a) {float distance = (float) Math.sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));return distance;}
}

好了,准备工作做好了,该克里马擦的实现绘制了(注: 克里马擦为陕西话,意为赶紧的)

package text.scc.com.scclock;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import java.util.ArrayList;
import java.util.List;/*** Created by scc on 2016/11/18.*/
public class GestureLock extends View {/*** 九个坐标点为三行三列的正方形,那就声明为一个二维数组吧*/private Point[][] points = new Point[3][3];/*** inited是是否为第一次初始化绘制,只需要初始化绘制一次就可以了.*/private boolean inited = false;/*** 定义三个位图对象,正常和按下和错误(找三张大小一样的图片就好了)*/private Bitmap bitmapPointError;private Bitmap bitmapPointNormal;private Bitmap bitmapPointPress;/*** 此为接口,用户是否已经画完了???*/private OnDrawFinishedListener listener;/*** 初始化paint画笔,后面的参数为消除锯齿*/private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);/*** 初始化绘制按下时的paint画笔*/private Paint pressPaint = new Paint();/*** 初始化绘制错误时的paint画笔*/private Paint errorPaint = new Paint();/*** 三个圆形位图对象的半径,不然的话在全屏的时候,位置会出现右下移*/private float bitmapR;/*** 手指按下时的坐标点的x值和y值*/private float mouseX, mouseY;/*** 是否在绘制过程中*/private boolean isDraw = false;/*** 来一个集合存储九个坐标点*/private ArrayList<Point> pointList = new ArrayList();/*** 来一个集合存储绘制好的图形的样式*/private ArrayList<Integer> passList = new ArrayList<>();/*** 来一个构造方法* @param context*/public GestureLock(Context context) {super(context);}/*** 再来一个构造方法* @param context* @param attrs*/public GestureLock(Context context, AttributeSet attrs) {super(context, attrs);}/*** 我还来一个构造方法* @param context* @param attrs* @param defStyleAttr*/public GestureLock(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);//如果没有初始化,就先初始化,调用init方法if (!inited) {init();}//当咱们初始化完了之后,就该绘制了.咱们定义一个方法叫做drawPoints来绘制点drawPoints(canvas);if (pointList.size() > 0) {Point a = pointList.get(0);for (int j = 1; j < pointList.size(); j++) {Point b = pointList.get(j);drawLine(canvas, a, b);a = b;}if (isDraw) {drawLine(canvas, a, new Point(mouseX, mouseY));}}}private void drawPoints(Canvas canvas) {/*** 此处呢咱们需要绘制的是一个二维数组的3*3的图形,双层循环嵌套一下就好* 外循环代表行,内循环代表列* 好了,开始绘制* 此处需要注意的就是要在点的x值和y值要减去自身图片的半径.* 原因是因为坐标点呢是图片的左上方开始计算的.减去后咱们就居中了哈,*/for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {if (points[i][j].state == Point.STATE_NORMAL) {//normalcanvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, mPaint);} else if (points[i][j].state == Point.STATE_PRESS) {//presscanvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, mPaint);} else {//errorcanvas.drawBitmap(bitmapPointError, points[i][j].x - bitmapR, points[i][j].y - bitmapR, mPaint);}}}}private void init() {/*** 对按下和错误时的状态的paint进行初始化*/pressPaint.setColor(Color.YELLOW);pressPaint.setStrokeWidth(6);errorPaint.setColor(Color.RED);errorPaint.setStrokeWidth(6);/*** 将资源drawable图片转换为bitmap位图对象*/bitmapPointError = BitmapFactory.decodeResource(getResources(), R.drawable.error);bitmapPointNormal = BitmapFactory.decodeResource(getResources(), R.drawable.normal);bitmapPointPress = BitmapFactory.decodeResource(getResources(), R.drawable.press);/*** 因为我的三个图片是一样大的,所以呢半径为任意一个图片的高度除以2即可*/bitmapR = bitmapPointError.getHeight() / 2;int width = getWidth();     //获得屏幕的宽度int height = getHeight();   //获得屏幕的高度int offset = Math.abs(width - height) / 2; //获得横屏和竖屏的偏移量offsetint offsetX, offsetY;    //水平和垂直的偏移量int space;if (width > height) {//横屏状态下(其中space为每个小正方形的边长)space = height / 4;offsetX = offset;offsetY = 0;} else {//竖屏状态下space = width / 4;offsetY = offset;offsetX = 0;}/*** 初始化九个点的坐标,横屏书评一起初始化了,这里有图,不然是不是有点乱哈*/points[0][0] = new Point(offsetX + space, offsetY + space);points[0][1] = new Point(offsetX + space * 2, offsetY + space);points[0][2] = new Point(offsetX + space * 3, offsetY + space);points[1][0] = new Point(offsetX + space, offsetY + space * 2);points[1][1] = new Point(offsetX + space * 2, offsetY + space * 2);points[1][2] = new Point(offsetX + space * 3, offsetY + space * 2);points[2][0] = new Point(offsetX + space, offsetY + space * 3);points[2][1] = new Point(offsetX + space * 2, offsetY + space * 3);points[2][2] = new Point(offsetX + space * 3, offsetY + space * 3);/*** 初始化之后让inited为true就好了,因为咱只初始化一遍就ok了*/inited = true;}/*** 好了,一切准给工作好了之后呢,咱们就开始来添加事件了.* @param event* @return*/@Overridepublic boolean onTouchEvent(MotionEvent event) {mouseX = event.getX();  //获得用户手指按下的x点mouseY = event.getY();  //获得用户手指按下的y点int[] ij;   //来个数组记录一下int i;      //坐标点x值int j;      //坐标点y值switch (event.getAction()) {case MotionEvent.ACTION_DOWN://此方法来恢复重新绘制resetPoints();//此方法来获得用户点击的点是否在我们绘制的距离之内//如果是,设置状态为按下,并添加进两个集合//一个集合是来装这点的坐标,一个集合是用来存储用户绘制的密码点ij = getSelectPoint();if (ij != null) {isDraw = true;i = ij[0];j = ij[1];points[i][j].state = Point.STATE_PRESS;pointList.add(points[i][j]);passList.add(i * 3 + j);}break;case MotionEvent.ACTION_MOVE://判断用户是否重复绘制,然后在一次添加进两个集合if (isDraw) {ij = getSelectPoint();if (ij != null) {i = ij[0];j = ij[1];if (!pointList.contains(points[i][j])) {points[i][j].state = Point.STATE_PRESS;pointList.add(points[i][j]);passList.add(i * 3 + j);}}}break;case MotionEvent.ACTION_UP://如果手指弹起,不绘制,调用接口判断是否和之前一致,不一致,状态为错误boolean valid = false;if (listener != null && isDraw){valid = listener.onDrawFinished(passList);}if (!valid){for (Point p : pointList) {p.state = Point.STATE_ERROR;}}isDraw = false;break;}this.postInvalidate();return true;}private int[] getSelectPoint() {Point pMouse = new Point(mouseX, mouseY);for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {if (points[i][j].distance(pMouse) < bitmapR) {int[] result = new int[2];result[0] = i;result[1] = j;return result;}}}return null;}private void drawLine(Canvas canvas, Point a, Point b) {if (a.state == Point.STATE_PRESS) {canvas.drawLine(a.x, a.y, b.x, b.y, pressPaint);} else if (a.state == Point.STATE_ERROR) {canvas.drawLine(a.x, a.y, b.x, b.y, errorPaint);}}public void resetPoints() {pointList.clear();passList.clear();for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {points[i][j].state = Point.STATE_NORMAL;}}this.postInvalidate();}public interface OnDrawFinishedListener {boolean onDrawFinished(List<Integer> passList);}public void setOnDrawFinishedListener(OnDrawFinishedListener listener){this.listener = listener;}
}

好了,到这里基本就ok了,图片的话我就不上了,因为我不会录制GIF图片,哈哈,有兴趣的各位工友的话,可以复制代码自己试一个demo就可以了..当然我也是个渣渣,感谢OPEN中的一个大神的此段代码的开发,感谢岗位工友的阅读,套用我们公司的一句话:”互帮互助,成就你我”,最后送各位工友一个程序猿段子,毕竟每天开发和维护工作我们都是很累的,relax一下.

女神:你能让这个论坛的人都吵起来,我今晚就跟你走。
程序猿:PHP语言是最好的语言!论坛炸锅了,各种吵架。
女神:服了你了,我们走吧,你想干啥都行。
程序猿:今天不行,我一定要说服他们,PHP语言是最好的语言。

Android 手势密码相关推荐

  1. android手势密码源码,Android自定义UI手势密码改进版源码下载

    在之前文章的铺垫下,再为大家分享一篇:Android手势密码,附源码下载,不要错过. 先看第一张图片的布局文件 activity_main.xml xmlns:tools="http://s ...

  2. Android手势密码view笔记(一)

    前言:不知不觉已经在这座陌生又熟悉的城市呆了一年多了,说不出什么感觉,可是即使是自己感觉自己没什么变化,但是周围的事物却不断的在变,不知道自己选择的路未来如何,但是当下我还是会努力.努力.再努力的,加 ...

  3. android手势密码csdn,Android手势密码LockPatternView、LockPasswordUtils、LockPatternUtils等分析...

    Android手势密码LockPatternView.LockPasswordUtils.LockPatternUtils 在使用别人写的这个手势密码的时候,我们通常是有自己的需求,可能这里的代码很多 ...

  4. Android手势密码探索

    Android 智能手机在全球市场有着极高的市场占有率,越来越受到广大消费者的青睐.但 Android 作为开源操作系统,且很容易可以获得系统 root 权限,Android 系统的安全问题也是用户和 ...

  5. Android 手势密码

    最近看了慕课网一老师的视频,关于手势密码的研究,挺不错的,不过没上传源码,还有就是旋转角度的计算个人感觉不太好,于是整理出源代码如下: import java.util.ArrayList; impo ...

  6. android 手势密码逻辑,[Android开发实战]Android手势密码(支付宝手势密码)实现(支持2.x)...

    原创文章,转载请注明出处:http://blog.csdn.net/ruils/article/details/17081207 在很多安全性比较高的应用程序中,每次打开程序,都会有让用户输入密码,这 ...

  7. android 手势密码功能sdk,利用ActivityLifecycleCallBack监控app前后台状态切换,实现手势密码即九宫格解锁...

    转载注明出处:http://blog..net/coderder/article/details/51063493 利用ActivityLifecycleCallbacks监控app前后台状态切换,实 ...

  8. 招财进宝手势锁,Android手势密码的实现

    这几个月都是在做招财进宝项目,招财进宝是盛大网络旗下,盛付通支付服务有限公司最新推出的,一款高收益低风险的理财APP,有兴趣的可以下载玩玩,收益不错哦!!! 招财进宝下载地址:http://8.she ...

  9. android手势第一次设置密码_[Android开发实战]Android手势密码(支付宝手势密码)实现(支持2.x) | 学步园...

    在很多安全性比较高的应用程序中,每次打开程序,都会有让用户输入密码,这些安全性比较高的程序,密码也会相对复杂,在手机上输入起来,就会不大方便,至少要切换一次输入法,对用户体验造成不好的影响,在移动互联 ...

  10. Android手势密码

    一.简介 1.本篇博文给大家介绍手势密码的绘制,首先看一下效果,如下:分为设置手势密码与验证手势密码: 二.结构分析: 如上图所示,我们在创建View之前,需将基本思路理清,我大致介绍一下我的理解: ...

最新文章

  1. delphi 调用dll 整形返回值_VS2015 编写C++ DLL库及C++、 C#、python 调用
  2. PHP获取远程文件内容
  3. 光伏巨头“脱轨” 英利确认债务重组
  4. Kylin 2.6.0JDBC方式访问
  5. Unity 如何修改 particle system 的 start color 属性
  6. 公众号跳转小程序首次没有数据_小程序如何从“0”开始运营,变成获客神器...
  7. Numpy数据二进制化
  8. Nginx面试题总结
  9. Android中 Bitmap转JPG PNG
  10. 繁星屠龙软件下载_酷狗繁星屠龙下载
  11. python 拼音地名对应关系,Python使用百度地图API根据地名获取相应经纬度
  12. python 图像处理 书籍_清华大学出版社-图书详情-《深度学习技术图像处理入门》...
  13. 收藏:关于3g手机的市场调查报告
  14. Twincat3 硬件: 台湾DFI工业控制器,CPU1.1GHZ,RAM512
  15. 怎么把用c语言开发的程序变成软件
  16. POI事件模式读取Excel 2003文件
  17. php 2038年,php如何取2038年后的时间戳|php时间日期处理到2038年之后该怎么办 - PS下...
  18. (c++)五分制成绩(函数实现)
  19. Arduino ESP8266读取土壤湿度传感器 ADC
  20. Enhancer和MethodInterceptor的需要导入的jar

热门文章

  1. 【数据结构】:二叉树,线索二叉树,排序二叉树,AVL树
  2. 分布式数据库 Snapshot 快照功能实现解密
  3. 安捷伦自动测试软件,使用AgilentB1500AEasyEXPERT软件创建测试序列-Keysight.PDF
  4. 使用 Laravel 和 Vue 创建单页应用程序
  5. 今年工资加了,年终奖却少了~~
  6. 查询异常:java.sql.SQLException: HOUR_OF_DAY: 0 -> 1
  7. 在你的计算机上安装 PrestaShop 1.6
  8. 阿里云存储和用户认证(预约挂号项目第九部分)
  9. cmd在运行程序时突然卡住的原因与解决方法
  10. HealthKit开发快速入门教程之HealthKit的主要类型数据