手势密码(二)

2024-08-31 23:38
文章标签 密码 手势

本文主要是介绍手势密码(二),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!


代码地址下载

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MainActivity" ><TextView android:layout_width="match_parent"android:layout_height="wrap_content"android:gravity="center"android:text="请输入密码"android:id="@+id/text"/><com.example.lockpatterview.LockPatterViewandroid:id="@+id/lock"android:layout_weight="1"android:layout_width="match_parent"android:layout_height="0dp" /></LinearLayout>

MainActivity

package com.example.lockpatterview;import com.example.lockpatterview.LockPatterView.OnPatterChangeLister;import android.os.Bundle;
import android.text.TextUtils;
import android.widget.TextView;
import android.widget.Toast;
import android.app.Activity;public class MainActivity extends Activity implements OnPatterChangeLister {LockPatterView lock;TextView text;String p = "14789";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);text = (TextView) findViewById(R.id.text);lock = (LockPatterView) findViewById(R.id.lock);lock.SetOnPatterChangeLister(this);}@Overridepublic void onPatterChange(String passwordStr) {if (!TextUtils.isEmpty(passwordStr)) {if (passwordStr.equals(p)) {text.setText(passwordStr);} else {text.setText("密码错误");lock.errorPoint();}}else {Toast.makeText(MainActivity.this, "至少连接5点", 0).show();}}@Overridepublic void onPatterStart(boolean isStart) {if (isStart) {text.setText("请绘制图案");}}}

LockPatterView

package com.example.lockpatterview;import java.util.ArrayList;
import java.util.List;import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class LockPatterView extends View {private static final int POINT_SIZE = 5;private Point[][] points = new Point[3][3];private Matrix matrix = new Matrix();private float width, height, offstartY, moveX, moveY;;private Bitmap bitmap_pressed, bitmap_normal, bitmap_error, bitmap_line,bitmap_line_error;private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);private List<Point> pointList = new ArrayList<LockPatterView.Point>();private OnPatterChangeLister onPatterChangeLister;/*** 构造函数*/public LockPatterView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);}public LockPatterView(Context context, AttributeSet attrs) {super(context, attrs);}public LockPatterView(Context context) {super(context);}/********************************************************** 绘制9宫格* movePoint代表鼠标在移动,但是不是9宫格里面的点* isInit是否初始化过9个点* isSelect 点位是否被选中状态* isFinish 是否绘制完毕*/private boolean isInit, isSelect, isFinish, movePoint;@Overrideprotected void onDraw(Canvas canvas) {// 第一次没有初始化就进行初始化,一旦初始化就不在初始化工作了,isInit的意思是---默认没有初始化过if (!isInit) {// 初始化9个点initPoints();}// 绘制9个点points2Canvas(canvas);if (pointList.size() > 0) {Point a = pointList.get(0);// 绘制九宫格坐标点for (int i = 0; i < pointList.size(); i++) {Point b = pointList.get(i);line2Canvas(canvas, a, b);a = b;}// 绘制鼠标坐标点if (movePoint) {line2Canvas(canvas, a, new Point(moveX, moveY));}}}/*** 初始化9个点位 获取点位的3种状态 线的2种状态 以及9点的坐标位置 以及初始化密码操作 isInit=* true设置状态--下次不必初始化话工作了*/private void initPoints() {// 获取布局宽高width = getWidth();height = getHeight();// 横屏和竖屏offstartY = (height - width) / 2;// 图片资源bitmap_normal = BitmapFactory.decodeResource(getResources(),R.drawable.btn_circle_normal);bitmap_pressed = BitmapFactory.decodeResource(getResources(),R.drawable.btn_circle_pressed);bitmap_error = BitmapFactory.decodeResource(getResources(),R.drawable.btn_circle_selected);bitmap_line = BitmapFactory.decodeResource(getResources(),R.drawable.ddd);bitmap_line_error = BitmapFactory.decodeResource(getResources(),R.drawable.qqq);points[0][0] = new Point(width / 4, offstartY + width / 4);points[0][1] = new Point(width / 2, offstartY + width / 4);points[0][2] = new Point(width / 4 * 3, offstartY + width / 4);points[1][0] = new Point(width / 4, offstartY + width / 4 * 2);points[1][1] = new Point(width / 2, offstartY + width / 4 * 2);points[1][2] = new Point(width / 4 * 3, offstartY + width / 4 * 2);points[2][0] = new Point(width / 4, offstartY + width / 4 * 3);points[2][1] = new Point(width / 2, offstartY + width / 4 * 3);points[2][2] = new Point(width / 4 * 3, offstartY + width / 4 * 3);// 设置密码1--9int index = 1;for (Point[] points : this.points) {for (Point point : points) {point.index = index;index++;}}// 初始化完成isInit = true;}/*** 将9个点绘制到画布 循环遍历9个点位, 根据3种不同的状态绘制3种不同的9个点位*/private void points2Canvas(Canvas canvas) {// 循环遍历9个点位for (int i = 0; i < points.length; i++) {// 循环遍历每行的3个点位for (int j = 0; j < points[i].length; j++) {// 获取依次的某个点位Point point = points[i][j];if (point.state == Point.STATE_PRESSED) {// (Bitmap bitmap, float left, float top, Paint paint)canvas.drawBitmap(bitmap_pressed,point.x - bitmap_normal.getWidth() / 2, point.y- bitmap_normal.getHeight() / 2, paint);} else if (point.state == Point.STATE_ERROR) {canvas.drawBitmap(bitmap_error,point.x - bitmap_normal.getWidth() / 2, point.y- bitmap_normal.getHeight() / 2, paint);} else {canvas.drawBitmap(bitmap_normal,point.x - bitmap_normal.getWidth() / 2, point.y- bitmap_normal.getHeight() / 2, paint);}}}}/*** 画线*/public void line2Canvas(Canvas canvas, Point a, Point b) {// 线的长度--2点之间的距离float linelength = (float) Point.distance(a, b);// 获取2点之间的角度float degress = getDegrees(a, b);//根据a点进行旋转canvas.rotate(degress, a.x, a.y);if (a.state == Point.STATE_PRESSED) {// xy方向上的缩放比例matrix.setScale(linelength / bitmap_line.getWidth(), 1);matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y- bitmap_line.getHeight() / 2);canvas.drawBitmap(bitmap_line, matrix, paint);} else {matrix.setScale(linelength / bitmap_line.getWidth(), 1);matrix.postTranslate(a.x - bitmap_line.getWidth() / 2, a.y- bitmap_line.getHeight() / 2);canvas.drawBitmap(bitmap_line_error, matrix, paint);}//画线完毕回归角度canvas.rotate(-degress, a.x, a.y);}// 获取角度public float getDegrees(Point pointA, Point pointB) {return (float) Math.toDegrees(Math.atan2(pointB.y - pointA.y, pointB.x- pointA.x));}/***************************************************************************** onTouch事件处理*/@Overridepublic boolean onTouchEvent(MotionEvent event) {moveX = event.getX();moveY = event.getY();movePoint = false;isFinish = false;Point point = null;switch (event.getAction()) {//只要按下操作,就代表重新绘制界面case MotionEvent.ACTION_DOWN:if (onPatterChangeLister != null) {onPatterChangeLister.onPatterStart(true);}// 每次按下,都需要清空之前的集合resetPoint();// 检测是不是在九宫格内point = chechSelectPoint();if (point != null) {//如果按下的位置在9宫格内,就改成状态为trueisSelect = true;}break;case MotionEvent.ACTION_MOVE:if (isSelect) {// 检测是不是在九宫格内point = chechSelectPoint();if (point == null) {movePoint = true;}}break;case MotionEvent.ACTION_UP://绘制完毕,点位状态改为未选中isFinish = true;isSelect = false;break;}// 如果没有绘制完毕,如果九宫格处于选中状态if (!isFinish && isSelect && point != null) {// 交叉点if (crossPoint(point)) {movePoint = true;} else {// 新点point.state = Point.STATE_PRESSED;pointList.add(point);}}// 绘制结束if (isFinish) {// 绘制不成立if (pointList.size() == 1) {// resetPoint();errorPoint();} else if (pointList.size() < POINT_SIZE && pointList.size() > 0) {// 绘制错误errorPoint();if (onPatterChangeLister != null) {onPatterChangeLister.onPatterChange(null);}} else {if (onPatterChangeLister != null) {String pass = "";for (int i = 0; i < pointList.size(); i++) {pass = pass + pointList.get(i).index;}if (!TextUtils.isEmpty(pass)) {onPatterChangeLister.onPatterChange(pass);}}}}postInvalidate();return true;}/*** 重新绘制*/public void resetPoint() {for (int i = 0; i < pointList.size(); i++) {Point point = pointList.get(i);point.state = Point.STATE_NORMAL;}pointList.clear();}/*** 检查是否选中*/private Point chechSelectPoint() {for (int i = 0; i < points.length; i++) {for (int j = 0; j < points[i].length; j++) {Point point = points[i][j];if (Point.with(point.x, point.y, bitmap_normal.getWidth() / 2,moveX, moveY)) {return point;}}}return null;}/*** 交叉点*/private boolean crossPoint(Point point) {if (pointList.contains(point)) {return true;} else {return false;}}/*** 绘制错误*/public void errorPoint() {for (Point point : pointList) {point.state = Point.STATE_ERROR;}}/************************************************************************ 自定义的点*/public static class Point {// 正常public static int STATE_NORMAL = 0;// 选中public static int STATE_PRESSED = 1;// 错误public static int STATE_ERROR = 2;public float x, y;public int index = 0, state = 0;public Point() {};public Point(float x, float y) {this.x = x;this.y = y;}/*** 两点之间的距离*/public static double distance(Point a, Point b) {return Math.sqrt(Math.abs(a.x - b.x) * Math.abs(a.x - b.x)+ Math.abs(a.y - b.y) * Math.abs(a.y - b.y));}/***/public static boolean with(float paintX, float pointY, float r,float moveX, float moveY) {return Math.sqrt((paintX - moveX) * (paintX - moveX)+ (pointY - moveY) * (pointY - moveY)) < r;}}/*** 图案监听器*/public static interface OnPatterChangeLister {void onPatterChange(String passwordStr);void onPatterStart(boolean isStart);}/*** 设置图案监听器*/public void SetOnPatterChangeLister(OnPatterChangeLister changeLister) {if (changeLister != null) {this.onPatterChangeLister = changeLister;}}
}


这篇关于手势密码(二)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125319

相关文章

SpringSecurity 认证、注销、权限控制功能(注销、记住密码、自定义登入页)

《SpringSecurity认证、注销、权限控制功能(注销、记住密码、自定义登入页)》SpringSecurity是一个强大的Java框架,用于保护应用程序的安全性,它提供了一套全面的安全解决方案... 目录简介认识Spring Security“认证”(Authentication)“授权” (Auth

Oracle登录时忘记用户名或密码该如何解决

《Oracle登录时忘记用户名或密码该如何解决》:本文主要介绍如何在Oracle12c中忘记用户名和密码时找回或重置用户账户信息,文中通过代码介绍的非常详细,对同样遇到这个问题的同学具有一定的参... 目录一、忘记账户:二、忘记密码:三、详细情况情况 1:1.1. 登录到数据库1.2. 查看当前用户信息1.

SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)

《SpringBoot使用Jasypt对YML文件配置内容加密的方法(数据库密码加密)》本文介绍了如何在SpringBoot项目中使用Jasypt对application.yml文件中的敏感信息(如数... 目录SpringBoot使用Jasypt对YML文件配置内容进行加密(例:数据库密码加密)前言一、J

MySQL9.0默认路径安装下重置root密码

《MySQL9.0默认路径安装下重置root密码》本文主要介绍了MySQL9.0默认路径安装下重置root密码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录问题描述环境描述解决方法正常模式下修改密码报错原因问题描述mysqlChina编程采用默认安装路径,

MySQL修改密码的四种实现方式

《MySQL修改密码的四种实现方式》文章主要介绍了如何使用命令行工具修改MySQL密码,包括使用`setpassword`命令和`mysqladmin`命令,此外,还详细描述了忘记密码时的处理方法,包... 目录mysql修改密码四种方式一、set password命令二、使用mysqladmin三、修改u

电脑密码怎么设置? 一文读懂电脑密码的详细指南

《电脑密码怎么设置?一文读懂电脑密码的详细指南》为了保护个人隐私和数据安全,设置电脑密码显得尤为重要,那么,如何在电脑上设置密码呢?详细请看下文介绍... 设置电脑密码是保护个人隐私、数据安全以及系统安全的重要措施,下面以Windows 11系统为例,跟大家分享一下设置电脑密码的具体办php法。Windo

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

mysql重置root密码的完整步骤(适用于5.7和8.0)

《mysql重置root密码的完整步骤(适用于5.7和8.0)》:本文主要介绍mysql重置root密码的完整步骤,文中描述了如何停止MySQL服务、以管理员身份打开命令行、替换配置文件路径、修改... 目录第一步:先停止mysql服务,一定要停止!方式一:通过命令行关闭mysql服务方式二:通过服务项关闭

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在