Android 图案解锁 9宫格密码解锁
序言 第一次写Android技术博客,不知道该如何下手。
背景 现在人们越来越重视自己的隐私,对于一些涉及用户隐私的应用,用户可能会希望在应用启动时必须先输入密码。传统的数字式密码记忆繁琐、容易破解,而图案解锁则可以解决这个问题。因此,在应用中添加图案解锁功能,可以提高应用的可靠性,获得用户的信任。
今天,我要介绍的是Android 的屏幕9宫格图形解锁,如果有什么不对的地方,望各位批评指正。直接上代码
1. 首先自定义图形密码控件,继承自View,创建并绘制9个点,并重写onTouchEvent方法。
public class GestureLock extends View {
private Point[][] points = new Point[3][3];
private boolean inited = false;
private boolean isDraw = false;
private ArrayList<Point> pointList = new ArrayList<Point>();
private ArrayList<Integer> passList = new ArrayList<Integer>();
private Bitmap bitmapPointError;
private Bitmap bitmapPointNormal;
private Bitmap bitmapPointPress;
private OnDrawFinishedListener listener;
float mouseX, mouseY;
private float bitmapR;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Paint pressPaint = new Paint();
Paint errorPaint = new Paint();
public GestureLock(Context context) {
super(context);
}
public GestureLock(Context context, AttributeSet attrs) {
super(context, attrs);
}
public GestureLock(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mouseX = event.getX();
mouseY = event.getY();
int[] ij;
int i, j;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
resetPoints();
ij = getSelectedPoint();
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 = getSelectedPoint();
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[] getSelectedPoint()
{
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;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!inited)
{
init();
}
drawPoints(canvas);
if (pointList.size() > 0)
{
Point a = pointList.get(0);
for (int i = 1;i < pointList.size(); i++)
{
Point b = pointList.get(i);
drawLine(canvas, a, b);
a = b;
}
if (isDraw)
{
drawLine(canvas, a, new Point(mouseX, mouseY));
}
}
}
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);
}
}
private void drawPoints(Canvas canvas)
{
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)
{
//Normal
canvas.drawBitmap(bitmapPointNormal, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);
}
else if (points[i][j].state == Point.STATE_PRESS)
{
//Press
canvas.drawBitmap(bitmapPointPress, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);
}
else {
//ERROR
canvas.drawBitmap(bitmapPointError, points[i][j].x - bitmapR, points[i][j].y - bitmapR, paint);
}
}
}
}
private void init()
{
pressPaint.setColor(Color.YELLOW);
pressPaint.setStrokeWidth(5);
errorPaint.setColor(Color.RED);
errorPaint.setStrokeWidth(5);
bitmapPointError = BitmapFactory.decodeResource(getResources(), R.mipmap.error);
bitmapPointNormal = BitmapFactory.decodeResource(getResources(), R.mipmap.normal);
bitmapPointPress = BitmapFactory.decodeResource(getResources(), R.mipmap.press);
bitmapR = bitmapPointError.getHeight() / 2;
int width = getWidth();
int height = getHeight();
int offset = Math.abs(width - height) / 2;
int offsetX, offsetY;
int space;
if(width > height)
{
space = height / 4;
offsetX = offset;
offsetY = 0;
}
else
{
space = width / 4;
offsetX = 0;
offsetY = offset;
}
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;
}
public void resetPoints()
{
passList.clear();
pointList.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;
}
}
辅助类 Point.java
public class Point {
public static int STATE_NORMAL = 0;
public static int STATE_PRESS = 1;
public static int STATE_ERROR = 2;
float x;
float y;
int state = STATE_NORMAL;
public Point(float x, float y)
{
this.x = x;
this.y = y;
}
public float distance(Point a)
{
float distance = (float)Math.sqrt((x - a.x) * (x - a.x) + (y - a.y) * (y - a.y));
return distance;
}
}
2.MainActivity.java 设置和检验密码锁。
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn_setting = (Button)findViewById(R.id.button);
Button btn_lock = (Button)findViewById(R.id.button2);
btn_setting.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, SettingActivity.class);
startActivity(intent);
}
});
btn_lock.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, LockActivity.class);
startActivity(intent);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
大体核心代码就是这些,后面有demo链接,可根据需要自行下载。
Demo源码下载
Android 图案解锁 9宫格密码解锁相关推荐
- android宫格式布局,Android 自定义TextView实现宫格布局,Drawable添加图片并控制宽高...
上图: 需求: 宫格布局(宽高一致,在屏幕上高度始终更随宽度变化) 图片在上文字在下布局 可以控制图片的宽高 布局完成,废话不多说直接上代码: /** * 时 间 : 2019/7/22 0022 * ...
- android 9宫格布局,android 朋友圈9宫格实现
icon9宫格效果.png 项目优化 2019-10-10 1.有人提出经常new ImageView耗内存, 我现在直接new 9个ImageView,可重复使用这几个ImageView 2.修复图 ...
- android 分组宫格菜单,android 九宫格(16宫格)控件
public class NineRectView extends ViewGroup { private Context ctx; private int wSize,hSize,row,colum ...
- android 仿微信9宫格图片
https://github.com/LukeMee/NineGridlayout 亲测好用
- PHP直播平台源码Android自定义View:9宫格图形手势解锁
9宫格图形解锁的操作就是在9个点上进行的,所以我们先定义一个点类,该类主要用于存储点的信息:坐标,状态,位置. public class Point {//正常状态public static int ...
- 9宫格解锁 android_android开发图案解锁学习记录一(九宫格的绘制)
图案解锁的原理: 九宫格解锁故名思议就是要有九个宫格:然后宫格间进行连线. 首先我们要先绘制九个点(宫格),确定位置,然后绘制不同的图案. 图案分为不同的状态:正常的状态,按下时的状态和错误的状态 当 ...
- 快给你的app上锁吧(android图案解锁)
序言:前两天因为项目的原因,去做了一下仿ios的数字解锁功能,然后写了那篇快给你的app上锁吧(android数字解锁),后来想到应用中常见的还有另外一种解锁就是绘制图案解锁,这两种解锁的布局看起来是 ...
- 1、迪文屏基于T5L_C51开发手势6宫格解锁
演示视频 1.概述 基于迪文屏DMG32240C028-03WTC屏的滑动手势6宫格解锁功能,该功能运用了触摸屏状态读取和坐标读取的功能(系统变量接口0x0016),绘图功能,需要配合变量图标显示等基 ...
- 值得推荐的 5 大 Android 手机密码解锁器
大多数 Android 用户使用唯一密码来保护他们的手机和重要数据.因此,忘记密码并被锁定在手机之外可能会令人沮丧.在这种情况下,使用安卓手机密码解锁器来解决问题是一个明智的选择.本文将介绍2023 ...
最新文章
- 摩卡签约印尼五大运营商之一CSM,进军东南亚市场
- 怎样解决MySQL数据库主从复制延迟的问题
- ashx获取客户端excel文件_Spring Boot实现导出Excel功能
- html中如何实现选择存储路径的功能_16687.VSM006分解03_如何打开HTML内嵌图像存储位置...
- HDU 1525 类Bash博弈
- python编译:setup.py添加.h头文件或者库的搜索路径
- thinkphp3.2.3入口文件详解
- maya mentray_mental ray渲染器下载
- eclipse环境变量配置步骤
- 浏览器全屏相关常用代码
- 渗透测试技巧总结更新篇2
- 图像着色 使用 OpenCV ,深度学习 进行 黑白图像着色
- 【深度学习】textCNN论文与原理
- php项目管理师什么,《项目管理师》填空题题目答案搜索在线
- sql 累计占比_sql 面试题(难题汇总)
- mysql 1308_Mysql恢复数据报ERROR1308:LEAVEwithnomatchinglabel_MySQL
- JS逆向瑞数4算法专题一
- ╭*★*╯浮华一场烟雨梦,叶落无痕情无踪╭*★*╯
- 哈工大软件构造Lab2实验
- 【转】计算机科学经典之作。。。