手势密码

主要View实现

    package com.view;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import java.util.ArrayList;/*** Created by thbpc on 2017/7/5 0005.*/public class GesturePwdView extends View implements View.OnTouchListener {public GesturePwdView(Context context) {this(context, null);}public GesturePwdView(Context context, @Nullable AttributeSet attrs) {this(context, attrs, 0);}public GesturePwdView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private Paint mBgPaint;private Paint mLinePaint;private int mWidth;private int mHeight;private int mPosition = 0;private int mPointRadius = 15;float mStartX;float mStartY;float mEndX;float mEndY;private CallBack mCallBack;private boolean isFirst = true;private boolean isError = false;private ArrayList<String> pointList = new ArrayList<>();private ArrayList<Integer> positionList1 = new ArrayList<>();private ArrayList<Integer> positionList2 = new ArrayList<>();private int mPointColor = Color.RED;private int mLineColor = Color.GREEN;private int mErrorLineColor = Color.RED;private float mLineStrokeWidth =0f;private void init() {mBgPaint = new Paint();mBgPaint.setAntiAlias(true);                       //设置画笔为无锯齿mBgPaint.setColor(mPointColor);                    //设置画笔颜色mBgPaint.setStyle(Paint.Style.FILL);//填充mLinePaint = new Paint();mLinePaint.setAntiAlias(true);mLinePaint.setColor(mLineColor);mLinePaint.setStyle(Paint.Style.STROKE);setOnTouchListener(this);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);if (widthSpecMode == MeasureSpec.EXACTLY || widthSpecMode == MeasureSpec.AT_MOST) {mWidth = widthSpecSize;} else {mWidth = 0;}if (heightSpecMode == MeasureSpec.AT_MOST || heightSpecMode == MeasureSpec.UNSPECIFIED) {mHeight = dipToPx(15);} else {mHeight = heightSpecSize;}setMeasuredDimension(mWidth, mHeight);}private int dipToPx(int dip) {float scale = getContext().getResources().getDisplayMetrics().density;return (int) (dip * scale + 0.5f * (dip >= 0 ? 1 : -1));}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);mLinePaint.setStrokeWidth(mLineStrokeWidth);canvas.drawCircle(mPointRadius, mPointRadius, mPointRadius, mBgPaint);//圆心坐标canvas.drawCircle(mWidth / 2, 0 + mPointRadius, mPointRadius, mBgPaint);canvas.drawCircle(mWidth - mPointRadius, mPointRadius, mPointRadius, mBgPaint);canvas.drawCircle(0 + mPointRadius, mHeight / 2, mPointRadius, mBgPaint);canvas.drawCircle(mWidth / 2, mHeight / 2, mPointRadius, mBgPaint);canvas.drawCircle(mWidth - mPointRadius, mHeight / 2, mPointRadius, mBgPaint);canvas.drawCircle(0 + mPointRadius, mHeight - mPointRadius, mPointRadius, mBgPaint);canvas.drawCircle(mWidth / 2, mHeight - mPointRadius, mPointRadius, mBgPaint);canvas.drawCircle(mWidth - mPointRadius, mHeight - mPointRadius, mPointRadius, mBgPaint);switch (mPosition) {case 1:drawGradually(canvas, 0 + mPointRadius, 0 + mPointRadius, mBgPaint);break;case 2:drawGradually(canvas, mWidth / 2, 0 + mPointRadius, mBgPaint);break;case 3:drawGradually(canvas, mWidth - mPointRadius, 0 + mPointRadius, mBgPaint);break;case 4:drawGradually(canvas, 0 + mPointRadius, mHeight / 2, mBgPaint);break;case 5:drawGradually(canvas, mWidth / 2, mHeight / 2, mBgPaint);break;case 6:drawGradually(canvas, mWidth - mPointRadius, mHeight / 2, mBgPaint);break;case 7:drawGradually(canvas, 0 + mPointRadius, mHeight - mPointRadius, mBgPaint);break;case 8:drawGradually(canvas, mWidth / 2, mHeight - mPointRadius, mBgPaint);break;case 9:drawGradually(canvas, mWidth - mPointRadius, mHeight - mPointRadius, mBgPaint);break;}mPosition = 0;if (isError) {mLinePaint.setColor(mErrorLineColor);} else {mLinePaint.setColor(mLineColor);}for (int i = 0; i < pointList.size(); i++) {if (i < pointList.size() - 1 && pointList.size() > 1) {String[] split1 = pointList.get(i).split(",");String[] split2 = pointList.get(i + 1).split(",");canvas.drawLine(Float.parseFloat(split1[0]), Float.parseFloat(split1[1]),Float.parseFloat(split2[0]), Float.parseFloat(split2[1]), mLinePaint);} else {String[] split = pointList.get(i).split(",");canvas.drawLine(Float.parseFloat(split[0]), Float.parseFloat(split[1]), mEndX, mEndY, mLinePaint);}}}private void drawGradually(final Canvas canvas, final int cx, final int cy, final Paint bgPaint) {canvas.drawCircle(cx, cy, mPointRadius + 5, bgPaint);canvas.drawCircle(cx, cy, mPointRadius + 10, bgPaint);canvas.drawCircle(cx, cy, mPointRadius + 15, bgPaint);canvas.drawCircle(cx, cy, mPointRadius + 10, bgPaint);canvas.drawCircle(cx, cy, mPointRadius + 5, bgPaint);}@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:float x = event.getX();float y = event.getY();float[] test = test(x, y);if (test != null) {mStartX = test[0];mStartY = test[1];String s = test[0] + "," + test[1];if (!pointList.contains(s)) {pointList.add(test[0] + "," + test[1]);}}break;case MotionEvent.ACTION_MOVE:float moveX = event.getX();float moveY = event.getY();float[] moveTest = test(moveX, moveY);if (moveTest != null) {drawLine(moveTest[0], moveTest[1]);} else {mEndX = moveX;mEndY = moveY;invalidate();}break;case MotionEvent.ACTION_UP:mPosition = 0;if (pointList.size() < 4) {pointList.clear();if (isFirst) {positionList1.clear();} else {positionList2.clear();}} else {String s = pointList.get(pointList.size() - 1);String[] split = s.split(",");mEndX = Float.parseFloat(split[0]);mEndY = Float.parseFloat(split[1]);setEnabled(false);if (mCallBack != null) {if (isFirst) {mCallBack.onComplete1(positionList1);} else {mCallBack.onComplete2(positionList2);}}}invalidate();break;}return true;}private void drawLine(float x, float y) {if (pointList.size() == 0) {//当集合为0时,第一个传来的坐标为起始点mStartX = x;mStartY = y;}String s = x + "," + y;if (!pointList.contains(s)) {//不包含再添加,否则重复pointList.add(x + "," + y);mEndX = x;mEndY = y;mStartX = x;//设置为下次绘制起始点mStartY = y;}invalidate();}private void addPointPosition(int position) {if (isFirst) {if (!positionList1.contains(position)) {mPosition = position;positionList1.add(position);VibratorUtil.Vibrate(getContext(), 40);   //震动}} else {if (!positionList2.contains(position)) {mPosition = position;positionList2.add(position);VibratorUtil.Vibrate(getContext(), 40);   //震动}}}private float[] test(float x, float y) {//判断第一排if (x < 0 + mPointRadius + 50 && x > 0 + mPointRadius - 50 &&y < 0 + mPointRadius + 50 && y + mPointRadius > 0 - 50) {addPointPosition(1);return new float[]{0 + mPointRadius, 0 + mPointRadius};} else if (x < mWidth / 2 + 50 && x > mWidth / 2 - 50 &&y < 0 + mPointRadius + 50 && y > 0 + mPointRadius - 50) {addPointPosition(2);return new float[]{mWidth / 2, 0 + mPointRadius};} else if (x < mWidth - mPointRadius + 50 && x > mWidth - mPointRadius - 50 &&y < 0 + mPointRadius + 50 && y > 0 + mPointRadius - 50) {addPointPosition(3);return new float[]{mWidth - mPointRadius, 0 + mPointRadius};//判断第二排} else if (x < 0 + mPointRadius + 50 && x > 0 + mPointRadius - 50 &&y < mHeight / 2 + 50 && y > mHeight / 2 - 50) {addPointPosition(4);return new float[]{0 + mPointRadius, mHeight / 2};} else if (x < mWidth / 2 + 50 && x > mWidth / 2 - 50 &&y < mHeight / 2 + 50 && y > mHeight / 2 - 50) {addPointPosition(5);return new float[]{mWidth / 2, mHeight / 2};} else if (x < mWidth - mPointRadius + 50 && x > mWidth - mPointRadius - 50 &&y < mHeight / 2 + 50 && y > mHeight / 2 - 50) {addPointPosition(6);return new float[]{mWidth - mPointRadius, mHeight / 2};//判断第三排} else if (x < 0 + mPointRadius + 50 && x > 0 + mPointRadius - 50 &&y < mHeight - mPointRadius + 50 && y > mHeight - mPointRadius - 50) {addPointPosition(7);return new float[]{0 + mPointRadius, mHeight - mPointRadius};} else if (x < mWidth / 2 + 50 && x > mWidth / 2 - 50 &&y < mHeight - mPointRadius + 50 && y > mHeight - mPointRadius - 50) {addPointPosition(8);return new float[]{mWidth / 2, mHeight - mPointRadius};} else if (x < mWidth - mPointRadius + 50 && x > mWidth - mPointRadius - 50 &&y < mHeight - mPointRadius + 50 && y > mHeight - mPointRadius - 50) {addPointPosition(9);return new float[]{mWidth - mPointRadius, mHeight - mPointRadius};}return null;}/*** 重置状态*/public boolean reSet() {pointList.clear();//清除索引顺序集合if (isFirst) {positionList1.clear();//清除轨迹} else {positionList2.clear();//清除轨迹}isError = false;//错误置为falseinvalidate();setEnabled(true);//可交互return isFirst;}/*** 继续*/public void goOn() {pointList.clear();//清除索引顺序集合invalidate();setEnabled(true);//可交互isFirst = false;//设置第二次}public void setError() {isError = true;//错误,绘制红色线invalidate();//绘制}/*** 设置点的颜色** @param color*/public void setPointColor(int color) {this.mPointColor = color;}/*** 设置点半径** @param radius*/public void setPointRadius(int radius) {this.mPointRadius = radius;}public void setLineColor(int color) {this.mLineColor = color;}public void setLineStrokeWidth(float width) {this.mLineStrokeWidth = width;}public interface CallBack {void onComplete1(ArrayList<Integer> postionList);void onComplete2(ArrayList<Integer> postionList);}public void setCallBack(CallBack callBack) {this.mCallBack = callBack;}}

简单用法,xml布局

<com.view.GesturePwdViewandroid:id="@+id/gesturepwdview"android:layout_width="250dp"android:layout_height="250dp"android:layout_marginTop="50dp"/>

Demo下载
https://github.com/thubin233/GesturePwdView

手势密码 图形解锁 实现相关推荐

  1. php手势解锁,Appium-实现手势密码登陆

    前言: 前几天有人问我,手势登陆如何做?于是我找了一个APP试了试,所以本文来总结使用Python+Appium来实现手势密码登陆APP. 环境: MacOS:10.13.4 Appium-deskt ...

  2. android 图案解锁忘记了,安卓手机忘记图形解锁、锁屏密码的解决方法

    Android 手机的图形解锁倒是真的好用了,主要是方便新颖,并且便于记忆,自从有了图形解锁,很多人都不再使用密码屏幕锁了,图形解锁倒是好玩,但是经常换来换去的话就会造成一时间想不起哪个图形解锁图案才 ...

  3. canvas实现H5手势密码设置以及手势解锁

    前言 这段时间遇到了一个需求,'我的' 页面有一个快捷登录,用户可以设置手势密码.指纹.以及面部,这篇文章主要是说说手势密码,以前也没有接触过,真是人都麻了,上网查到了一些案例,但是终归和自己需求有所 ...

  4. 手把手教你写一个手势密码解锁View(GesturePasswordView)

    相信大家在很多的app肯定看到过手势密码解锁View,但是大家有没有想过怎么实现这样一个View,哈,接下来,小编手把手教大家教写一个GesturePasswordView. 先看一张效果图 要实现这 ...

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

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

  6. 自定义View----Android九宫格手势密码解锁

    好久没更新blog了,最近公司比较忙,旧的项目上线时间赶.加上新的项目又来了,于是导致都好久没去鸿洋的群里扯蛋了,做了一个不称职的管理员.说了好多遍的自定义萌系进度条都没有分享出来,在这给群里的各位说 ...

  7. OPPO R9S 锁屏手势密码,应用加密

    system/gesture.key 锁屏手势密码 system/password.key 锁屏数字密码 安卓的解锁图案一共有九个点,按顺序设定值为0×00-0×08(注意这里是十六进制),这九个值依 ...

  8. Android一步一步剖析+实现仿支付宝手势密码自定义View

    最近项目需求:要求在项目中添加手势密码和指纹验证,恰巧最近在苦练自定义View,于是参考了网上轮子和自己的理解,实现了如下的效果. 国际惯例:Without pic you say a JB(奖杯). ...

  9. 苹果 android专利,苹果新专利:类似Android但更复杂的图形解锁

    本周三,美国专利与商标局公布了2个苹果的专利申请,两则专利标题同为"手势解锁方法(Gesture entry techniques)",描述的是用户在屏幕上划出相应解锁图形后的解锁 ...

  10. Android招财进宝手势密码的实现

    分类: Android 小项目 2014-11-03 17:01  5918人阅读  评论(8)  收藏  举报 ANDROID 手势密码 手势密码锁 Android手势密码锁 目录(?)[+] 这几 ...

最新文章

  1. [Cake] 1. CI中的Cake
  2. [转]windows中断与共享的连接(samba)
  3. get;get属性器
  4. C# ?. 判斷Null值
  5. [SpringBoot2]拦截器
  6. python合并单元格 索引_python笔记:纵向合并表格
  7. 云原生的基石,一文读懂容器、Docker、Pod到底是什么!
  8. AD放置过孔按TAB键使过孔大小为设置值0.6/0.3
  9. Java 面试 ——可变参数、初始化数据块、设计秒杀系统
  10. 详解VMware虚拟机中添加新硬盘并挂载的方法
  11. 2014全国计算机等级考试四级数据库工程师考试大纲,全国计算机等级考试四级数据库工程师...
  12. 趋势移动或者移动应用2012
  13. gif表情制作软件怎么制作gif动图
  14. 3D建模要学多久才能接外包私活?
  15. (附源码)ssm无人机数据管理系统 毕业设计 111022
  16. 【JavaSE】算术运算符、关系运算符、逻辑运算符、赋值运算符与三元运算符
  17. 火车头php post提取内容,【火车头采集教程】轻而易举学会火车头采集(附带采集案例)...
  18. chinapay java_ECSHOP 银联电子支付(ChinaPay)插件 掉用JAVA签名
  19. 舵机PWM转模拟电压(带正反控制)
  20. 以开发之名|斗罗大陆:创造一个尽情探险的开放式游戏世界

热门文章

  1. 星外系统更换短信接口
  2. 局域网的分类:以太网、令牌环、FDDI、ATM、WLAN
  3. 基于SVM的手写字体识别
  4. 循环制比赛要赢几场可能(一定)晋级
  5. jmeter访问网址
  6. selenium: 登录QQ空间并破解滑块验证
  7. java水果仓库管理系统_java水果商城管理系统(界面框架代码)
  8. 一款开源的微信小程序商城项目,接外包直接拿去改改,就能用。。。
  9. matlab求解微积分
  10. java中画幅相机推荐_中画幅的初级入门选择-飞思645DF+