android自定义view之九宫格解锁

更多细节请看源码
https://github.com/que123567/lockview

  • 1. 定义一个类作为九宫格的格子

    包含坐标和索引(用来记录密码)
    point含三种状态分别对应三种不同情况下点的图片样式

package lockview;/*** Created by smaug on 2017/5/11.*/public class Point {public float x;public float y;private int index;public int getIndex() {return index;}public void setIndex(int index) {this.index = index;}public static final int STATU_NORNAL = 0;public static final int STATU_PRESSED = 1;public static final int STATU_ERROR = 2;public int state;public void setState(int state) {this.state = state;}public int getState() {return state;}public Point() {super();}public Point(float x, float y) {this.x = x;this.y = y;}public float getX() {return x;}public void setX(float x) {this.x = x;}public float getY() {return y;}public void setY(float y) {this.y = y;}
}
  • 2.新建类LockView继承自View
    重写onDraw()方法

    • 初始化点的时候根据获取当前屏幕的宽高,比对来确定当前状态是横屏还是竖屏
    • 从资源中获取Bitmap,将点设置成图像。
    @Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);initPoints();initPaint();    }private void drawPoints(Canvas canvas) {for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {Point point = points[i][j];if (point.getState() == Point.STATU_NORNAL) {//获取当前点的坐标,减去图片的半径得到left和top的坐标点canvas.drawBitmap(point_normal, point.x - br, point.y - br, null);} else if (point.getState() == Point.STATU_PRESSED) {canvas.drawBitmap(point_pressed, point.x - br, point.y - br, null);} else if (point.getState() == Point.STATU_ERROR) {canvas.drawBitmap(point_error, point.x - br, point.y - br, null);}}}}public class LockView extends View {private void initPoints() {width = getWidth();height = getHeight();if (height > width) {//竖屏offsetY = (height - width) / 2;height = width;} else { //横屏offsetX = (height - width) / 2;width = height;}/***     定义9个点的坐标*/points = new Point[row][colun];int index = 1;for (int i = 0; i < row; i++) {for (int j = 0; j < colun; j++) {points[i][j] = new Point(offsetX + (width / (row + 1)) * (i + 1), offsetY +(width / (colun + 1)) * (j + 1));points[i][j].setIndex(index);index++;}}/*** 从资源中获取Bitmap*/point_normal = BitmapFactory.decodeResource(getResources(), R.drawable.point_normal);point_pressed = BitmapFactory.decodeResource(getResources(), R.drawable.point_pressed);point_error = BitmapFactory.decodeResource(getResources(), R.drawable.point_error);br = point_normal.getWidth() / 2;}
}

显示结果如下图

  • 3.重写onTouchEvent
  case MotionEvent.ACTION_DOWN:reset();//先清空之前绘制的状态checkedPoint = checkPoint(eventX, eventY, br);if (checkedPoint != null) {isSelecte = true;checkedPoint.setState(Point.STATU_PRESSED);}break;

checkPoint()通过计算坐标距离判断当前手指坐标是否在point图片上

  private Point checkPoint(float eventX, float eventY, float br) {for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {Point point = points[i][j];double distance = getDistance(point.x, point.y, eventX, eventY);if (distance < br) {return point;}}}return null;}

getDistance()利用勾股定理计算坐标距离

private double getDistance(float x, float y, float eventX, float eventY) {return Math.sqrt(Math.abs(x - eventX) * Math.abs(x - eventX) + Math.abs(y - eventY) *Math.abs(y - eventY));}

这个时候手指接触都某个点,某个点的状态就会从normal转换为pressed,其对应的图片也会改变。

  • 4.添加点与点之间的连线
    LockView中定义一个Point类的List —>pointList 记录用户按下的点

  • 当pointList为空,即用户未按下任一点的时候不绘制线段,其余时刻都绘制

  • 绘制线段调用canvas的drawLine()方法,传入起始点x,y坐标与目标点x,y坐标与一个自定义的paint画笔绘制线段

 private void drawLine(Canvas canvas) {if (pointList.size() > 0) {Point a = pointList.get(0);for (int i = 1; i < pointList.size(); i++) {Point b = pointList.get(i);canvas.drawLine(a.x, a.y, b.x, b.y, paint);a = b;}if (!moveOnPoint) { //canvas.drawLine(a.x, a.y, eventX, eventY, paint);}}}

效果如图所示

  • 5.自动连接中间点

在九宫格中,如果用户跳开中间点只连接了头尾两个点,按照规则应该把中间点自动连上。

即在ACTION_MOVE过程中始终判断中间点是否被连入,而中间点的判断方式为首尾点坐标/2.

case MotionEvent.ACTION_MOVE:if (isSelecte) {checkedPoint = checkPoint(eventX, eventY, br);if (checkedPoint != null) {if (!pointList.contains(checkedPoint)) {middlePoint = checkPoint((checkedPoint.x + lastPoint.x) / 2, (checkedPoint.y + lastPoint.y) / 2, br);if (middlePoint != null) {middlePoint.setState(Point.STATU_PRESSED);}}checkedPoint.setState(Point.STATU_PRESSED);moveOnPoint = true;} else {moveOnPoint = false;}}break;
  • 6.此外,在绘制过程中会记录密码,在使用该LockView时可设置setOnLockSuccessed监听来判断,其中带有参数:正确密码-passward

    对应的,连接数少于5判定为连接失败,也有对应的监听事件。

 if (pointList != null) {if (pointList.size() == 1) {reset();//重置} else if (pointList.size() < 5) {//个数不足errorPoint();//绘制错误的图案if (onLockChangeListener != null) { //失败onLockChangeListener.setOnLockError();}} else if (pointList.size() >= 5) { //九宫格连接数应大于等于5StringBuilder passward = new StringBuilder();for (int i = 0; i < pointList.size(); i++) {int tmpIndex = pointList.get(i).getIndex();passward.append(tmpIndex + "");}if (onLockChangeListener != null)//成功onLockChangeListener.setOnLockSuccessed(passward);}}

作者:邱钟浩:原文地址

android自定义view之九宫格解锁相关推荐

  1. Android自定义View,九宫格解锁

    /   今日科技快讯   / 近日微软中国在其官方微博宣布,未来一年内将继续扩大在华招聘,员工总数预计突破1万人.在扩大招聘的基础上,微软还计划在未来三到五年内,对位于北京.上海及苏州的园区进行升级扩 ...

  2. 自定义View学习——九宫格解锁(LockPatternView)

    虽然现在的应用很少在使用九宫格解锁,不过系统的应用锁还是可以见到的.实现的效果如下: 分析 首先需要绘制出九宫格,每一个单元格有两个半径不同的同心圆. 当我们的手指在九宫格上触摸时,如果我们触摸在某个 ...

  3. android自定义View: 九宫格解锁

    本系列自定义View全部采用kt 系统:mac android studio: 4.1.3 kotlin version1.5.0 gradle: gradle-6.5-bin.zip 废话不多说,先 ...

  4. android 自定义view: 蛛网/雷达图(三)

    本系列自定义View全部采用kt 系统mac android studio: 4.1.3 kotlin version1.5.0 gradle: gradle-6.5-bin.zip 本篇效果: 蛛网 ...

  5. 自定义View之--九宫格图形密码锁

    前言: 很多金融和几大商业银行的APP,都使用了九宫格图形密码锁来增强资金账户的安全.我也是金融公司的一员,在空余的时候,写下这个view,可以说是明智之举. 效果预览 这样一个逻辑差不多可以满足基本 ...

  6. Android技术分享| 【Android 自定义View】多人视频通话控件

    [Android 自定义View]多人视频通话控件 *以上图片截自微信等待中界面 等待中界面 上图是微信多人视频通话时未接通的界面状态,可见每个人的 View 中大致需包含了以下元素. 头像 昵称 L ...

  7. Android自定义View —— TypedArray

    在上一篇中Android 自定义View Canvas -- Bitmap写到了TypedArray 这个属性 下面也简单的说一下TypedArray的使用 TypedArray 的作用: 用于从该结 ...

  8. Android 自定义View —— Canvas

    上一篇在android 自定义view Paint 里面 说了几种常见的Point 属性 绘制图形的时候下面总有一个canvas ,Canvas 是是画布 上面可以绘制点,线,正方形,圆,等等,需要和 ...

  9. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

最新文章

  1. oracle存储过程拼',【求助】关于oracle存储过程'字符串拼接'
  2. 抽象工厂模式设计模式_创新设计模式:抽象工厂模式
  3. python浅拷贝的说法_Python中List的复制(直接复制、浅拷贝、深拷贝)
  4. 服务器与本地文件共享文件夹,云服务器对本地服务器共享文件夹
  5. react hooks_React Hooks简介
  6. leetcode 384 打乱数组
  7. Ubuntu12.04键盘输入法系统无选择项
  8. ASP.Net的HtmlHelper和UrlHelper
  9. 鲁班学院java高级架构师_鲁班学院三期java架构师
  10. TVS管、稳压管、肖特基二极管
  11. python云计算有哪些岗位_云计算就业前景怎么样,包括哪些岗位,各岗位主要工作是什么?...
  12. 史上最全股票指标图文详解
  13. 一图看懂人工智能技术体系
  14. 可爱猫python_可爱猫微信机器人框架最新版以及使用教程
  15. 在线暴躁:script /问题
  16. CAD三维图形转化成二维图形的过程具体的步骤
  17. 五月集训-14【栈】
  18. 消防应急照明和疏散指示系统——集中控制型系统的设计与应用
  19. 数据仓库-你不知道的HSQL?
  20. 超好用的图片压缩网站

热门文章

  1. 从零学习知识图谱——01(知识图谱技术介绍)
  2. Wireshark抓包分析微信功能----tcp/ip选修课期末大作业
  3. 清华小学上册计算机教学案例,案例分析 清华小学 罗远琴
  4. 金庸的小说人生(1)
  5. 74ls175四人抢答器电路图_四人抢答器电路设计.doc
  6. 推荐一位从外包走进腾讯的朋友
  7. 5分钟学会cleos注册EOS主网账户、投票和发币
  8. 斐讯空气检测仪M1使用Easylink配置WIFI的图文教程
  9. 1000个手工绘制污渍笔刷
  10. 华师大计算机学院院士,华师大新建4大学院1个研究院顺应AI发展