android自定义手势解锁View
有时候为了程序的安全性,我们经常要采取一些安全措施,就像我们常用的支付宝那样,隔一定的时间再回到应用程序时会让用户利用手势去解锁应用程序,最近由于项目需求,也要求做这样一个功能,当用户切出本应用程序15分钟后回来,让用户手势解锁,整个需求的难点就在如何实现这个手势锁,开始一点头绪也没有,没有一点思路去实现这个手势解锁功能,在google了一番后看了一篇非常好的博客后,按照博主的思路的确是可以实现一个十分不错的手势锁View,也参考了下那位大神的代码,下面是我根据他的思路和代码片段实现的一个自定义手势解锁 View,先看效果图.
这是自定义View的初始效果图:
以下是绘制手势时的效果图:
下面是实现的demo代码:
package com.example.gesturelock;import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;import com.example.gesturelock.GestureLockView.OnGestureFinishListener;public class MyGestureLockView extends View {/*** 不同状态的画笔*/private Paint paintNormal;private Paint paintOnTouch;private Paint paintInnerCycle;private Paint paintLines;private Paint paintKeyError;private MyCycle[] cycles;private Path linePath = new Path();private List<Integer> linedCycles = new ArrayList<Integer>();private OnGestureFinishListener onGestureFinishListener;private String key;private int eventX, eventY;private boolean canContinue = true;private boolean result;private Timer timer;/*** 不同状态下的色值*/private int OUT_CYCLE_NORMAL = Color.rgb(108, 119, 138); // ������Բ��ɫprivate int OUT_CYCLE_ONTOUCH = Color.rgb(025, 066, 103); // ѡ����Բ��ɫprivate int INNER_CYCLE_ONTOUCH = Color.rgb(002, 210, 255); // ѡ����Բ��ɫprivate int LINE_COLOR = Color.argb(127, 002, 210, 255); // ��������ɫprivate int ERROR_COLOR = Color.argb(127, 255, 000, 000);public void setOnGestureFinishListener(OnGestureFinishListener onGestureFinishListener) {this.onGestureFinishListener = onGestureFinishListener;}public void setKey(String key) {this.key = key;}public MyGestureLockView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);init();}public MyGestureLockView(Context context, AttributeSet attrs) {super(context, attrs);init();}public MyGestureLockView(Context context) {super(context);init();}private void init() {paintNormal = new Paint();paintNormal.setAntiAlias(true);paintNormal.setStrokeWidth(3);paintNormal.setStyle(Paint.Style.STROKE);paintOnTouch = new Paint();paintOnTouch.setAntiAlias(true);paintOnTouch.setStrokeWidth(3);paintOnTouch.setStyle(Paint.Style.STROKE);paintInnerCycle = new Paint();paintInnerCycle.setAntiAlias(true);paintInnerCycle.setStyle(Paint.Style.FILL);paintLines = new Paint();paintLines.setAntiAlias(true);paintLines.setStyle(Paint.Style.STROKE);paintLines.setStrokeWidth(6);paintKeyError = new Paint();paintKeyError.setAntiAlias(true);paintKeyError.setStyle(Paint.Style.STROKE);paintKeyError.setStrokeWidth(3);}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubsuper.onMeasure(widthMeasureSpec, heightMeasureSpec);}@Overrideprotected void onLayout(boolean changed, int left, int top, int right,int bottom) {// TODO Auto-generated method stubsuper.onLayout(changed, left, top, right, bottom);int perSize = 0;if (cycles == null && (perSize = getWidth() / 6) > 0) {cycles = new MyCycle[9];for (int i = 0; i < 3; i++) {for (int j = 0; j < 3; j++) {MyCycle cycle = new MyCycle();cycle.setNum(i * 3 + j);cycle.setOx(perSize * (j * 2 + 1));cycle.setOy(perSize * (i * 2 + 1));cycle.setR(perSize * 0.5f);cycles[i * 3 + j] = cycle;}}}}/*** 绘制所需要绘制的内容*/@Overrideprotected void onDraw(Canvas canvas) {// TODO Auto-generated method stubsuper.onDraw(canvas);for (int i = 0; i < cycles.length; i++) {if (!canContinue && !result) {paintOnTouch.setColor(ERROR_COLOR);paintInnerCycle.setColor(ERROR_COLOR);paintLines.setColor(ERROR_COLOR);} else if (cycles[i].isOnTouch()) {paintOnTouch.setColor(OUT_CYCLE_ONTOUCH);paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH);paintLines.setColor(LINE_COLOR);} else {paintNormal.setColor(OUT_CYCLE_NORMAL);paintInnerCycle.setColor(INNER_CYCLE_ONTOUCH);paintLines.setColor(LINE_COLOR);}if (cycles[i].isOnTouch()) {canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(),cycles[i].getR(), paintOnTouch);drawInnerBuleCycle(cycles[i], canvas);} else {canvas.drawCircle(cycles[i].getOx(), cycles[i].getOy(),cycles[i].getR(), paintNormal);}}drawLine(canvas);}/*** 绘制大圆里的小圆* * @param canvas*/private void drawInnerBuleCycle(MyCycle cycle, Canvas canvas) {canvas.drawCircle(cycle.getOx(), cycle.getOy(), cycle.getR() / 3,paintInnerCycle);}private void drawLine(Canvas canvas) {linePath.reset();if (linedCycles.size() > 0) {for (int i = 0; i < linedCycles.size(); i++) {int index = linedCycles.get(i);if (i == 0) {// 设置为整条路径的起点linePath.moveTo(cycles[index].getOx(), cycles[i].getOy());} else {linePath.lineTo(cycles[i].getOx(), cycles[i].getOy());}}linePath.lineTo(eventX, eventY);canvas.drawPath(linePath, paintLines);}}/*** 根据手择时触摸点的不同,修改对应的状态值*/@Overridepublic boolean onTouchEvent(MotionEvent event) {if (canContinue) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:case MotionEvent.ACTION_MOVE:eventX = (int) event.getX();eventY = (int) event.getY();for (int i = 0; i < cycles.length; i++) {if (cycles[i].isPointIn(eventX, eventY)) {cycles[i].setOnTouch(true);if (!linedCycles.contains(cycles[i].getNum())) {linedCycles.add(cycles[i].getNum());}}}break;case MotionEvent.ACTION_UP:canContinue = false;StringBuffer sb = new StringBuffer();for (int i = 0; i < linedCycles.size(); i++) {sb.append(linedCycles.get(i));}result = key.equals(sb.toString());if (onGestureFinishListener != null) {onGestureFinishListener.OnGestureFinish(result);}timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {// 回到初始状态eventX = eventY = 0;for (int i = 0; i < cycles.length; i++) {cycles[i].setOnTouch(false);}linedCycles.clear();linePath.reset();canContinue = true;postInvalidate();}}, 1000);break;}}invalidate();return true;}
}
自定义圆类:
package com.example.gesturelock;public class MyCycle {private int ox; // Բ�ĺ�����private int oy; // Բ��������private float r; // �뾶����private Integer num; // ������ֵprivate boolean onTouch; // false=δѡ��public int getOx() {return ox;}public void setOx(int ox) {this.ox = ox;}public int getOy() {return oy;}public void setOy(int oy) {this.oy = oy;}public float getR() {return r;}public void setR(float r) {this.r = r;}public Integer getNum() {return num;}public void setNum(Integer num) {this.num = num;}public boolean isOnTouch() {return onTouch;}public void setOnTouch(boolean onTouch) {this.onTouch = onTouch;}public boolean isPointIn(int x, int y) {double distance = Math.sqrt((x - ox) * (x - ox) + (y - oy) * (y - oy));return distance < r;}
}
思路:
1.自定义一个 View和MyCircle类,将九个MyCircle类的实例绘制到View中.
2.处理onTouch事件,根据不同的事件修改MyCircle实例的状态,并调用更新invaildate更新View
3.重写onDraw()方法,根据不同的状态去重新绘制整个View
android自定义手势解锁View相关推荐
- Android 自定义手势解锁View
直接上代码了: /****@ClassName:GraphicsView*@author:WYL*@Date:2022/9/29*/ class GraphicsView : View {privat ...
- android view显示隐藏动画效果,Android 根据手势顶部View自动展示与隐藏效果
首先来看一下效果: 大体思路如下: 总体布局用了一个自定义的ViewGroup,里面包了两个View(top View,bottomView) 我在bottomView里放了ViewPager,里面又 ...
- android自定义滑块解锁,android 滑动解锁
通过android自定义View实现横向的滑动解锁,1.滑动到中间会自动返回到原始的位置,2.滑动到底部会自动解锁,会触发解锁的回调:首先看效果图如下: 实现以上部分一共分为三部分: 其中背景通过sh ...
- android自定义手势,Android编程实现自定义手势的方法详解
本文实例讲述了Android编程实现自定义手势的方法.分享给大家供大家参考,具体如下: 之前介绍过如何在Android程序中使用手势,主要是系统默认提供的几个手势,这次介绍一下如何自定义手势,以及如何 ...
- android自定义手势,Android实现自定义手势和识别手势的功能
这篇文章主要介绍了Android实现自定义手势和识别手势的功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 1. 先完成自定义手势的Activity 1.1 因 ...
- 自定义手势解锁锁控件
一.控件的使用 模仿市面上app的手势解锁功能,实现的小控件,将控件封装到了一个UIView上 二.核心原理技术 1.触摸事件 (1)UIView的触摸三个触摸响应事件:开始.移动.结束 (2)CGR ...
- Android实现手势解锁
自己实现过一个手势解锁, 觉得有一点用, 所以贴出来便于以后使用. 需求 9宫格解锁, 连接节点后, 节点之间会绘制连线. 节点被连接后会变色. 当手指继续绘制手势时, 最后一个节点会延伸出一条连线跟 ...
- android的手势解锁功能,Android应用开发之Android 5秒学会使用手势解锁功能
本文将带你了解Android应用开发Android 5秒学会使用手势解锁功能,希望本文对大家学Android有所帮助. Android手势解锁 本文讲述的是一个手势解锁的库,可以定制显示隐藏宫格点.路 ...
- Android 自定义手势键盘
自定义手势键盘 手势键盘有三种状态,初始状态.点击状态和错误状态,分别以下列三个图片显示. 2. 数据类CircleArea CircleArea类用来记录手势键盘的信息. static class ...
- android自定义滑块解锁,使用Android自定义控件实现滑动解锁九宫格
本文概述: 滑动解锁九宫格的分析: 1.需要自定义控件: 2.需要重写事件onTouchEvent(); 3.需要给九个点设置序号和坐标,这里用Map类就行: 4.需要判断是否到滑到过九点之一,并存储 ...
最新文章
- 使用datatables实现列宽设置、水平滚动条、显示某列部分内容
- 为什么二级菜单会被挡住_武夷红茶为什么是二级茶?我们平时喝的红茶会不会被加了糖?...
- goodFeaturesToTrack函数
- C语言a+++b的问题
- 【tensorflow】全连接层函数tf.layers.dense()原理
- ubuntu下无法在目录下创建文件夹,权限不足解决办法
- jQuery——siblings()方法
- 树莓派控制电机转速_怎样用树莓派控制直流电机的方向和速度
- Spring Boot 如何解决多个定时任务阻塞问题?
- Boost 1.34.0 终于5.12发布了
- 单例设计模式 (2)
- Android之改变控件的背景及形态
- 28.4 kvm介绍 28.5 Centos7上安装KVM 28.6 配置网卡 28.7 创建虚拟机安装CentOS7
- 一位大佬对于 Qt 学习的最全总结(三万字干货)
- 练习电脑键盘打字最好的网站
- Android移动应用程序开发
- python项目对接钉钉SDK
- 台式计算机读取不了移动硬盘,移动硬盘插入win7电脑一直无法识别的几种原因和解决方法...
- 我的世界win10版与java版_我的世界java版和win10版的区别
- Excel 合并一个工作簿中的所有工作表
热门文章
- Node.js:Webpack
- 数据库持久化ORM框架Hibernate、JPA、Mybatis、JOOQ和JDBC Template的比较
- JavaScript cookie js cookie设置
- PM_敏捷开发 Scrum vs Kanban,如何选择?
- ORB-SLAM3学习笔记-基本概念
- 论文阅读笔记(六)——GhostNet: More Features from Cheap Operations
- 深度学习中的Attention总结
- fastText、TextCNN、TextRNN……这里有一套NLP文本分类深度学习方法库供你选择
- 利用python批量处理Word文件——正文、标题
- PYTHON自动化Day9-发邮件、面向对象、类、私有、继承