Android实现九宫格图案解锁
(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun)
本文实例为大家分享了Android实现九宫格图案解锁的具体代码,供大家参考,具体内容如下
前言:自定义了一个九宫格的VIew来绘制九宫格图案,实现了绘制图案解锁的功能。
效果图如下:
1. 第一步
自定义九宫格View。
public class LockPatterView extends View { ? ? private static final int POINT_SIZE = 5; ? ? private Point[][] points = new Point[3][3]; ? ? private boolean isInit,isSelect,isFinish,movePoint; ? ? private Matrix matrix = new Matrix(); ? ? private float width,height,offstartX,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<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); ? ? } ? ? @Override ? ? protected void onDraw(Canvas canvas) { ? ? ? ? if (!isInit) { ? ? ? ? ? ? initPoints(); ? ? ? ? } ? ? ? ? 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)); ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? /** ? ? ?* @param canvas ? ? ?*/ ? ? private void points2Canvas(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.state == Point.STATE_PRESSED) { ? ? ? ? ? ? ? ? ? ? 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); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? } ? ? /** ? ? ?* ? ? ?* @param canvas ? ? ?* @param ? ? ?* @param ? ? ?*/ ? ? public void line2Canvas(Canvas canvas,Point a,Point b){ ? ? ? ? float linelength = (float) Point.distance(a, b); ? ? ? ? float degress = getDegrees(a,b); ? ? ? ? canvas.rotate(degress, a.x, a.y); ? ? ? ? if (a.state == Point.STATE_PRESSED) { ? ? ? ? ? ? matrix.setScale(linelength / bitmap_line.getWidth(), 1); ? ? ? ? ? ? matrix.postTranslate(a.x, a.y); ? ? ? ? ? ? canvas.drawBitmap(bitmap_line, matrix, paint); ? ? ? ? }else{ ? ? ? ? ? ? matrix.setScale(linelength / bitmap_line.getWidth(), 1); ? ? ? ? ? ? matrix.postTranslate(a.x, a.y); ? ? ? ? ? ? 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)); ? ? } ? ? /** ? ? ?*/ ? ? private void initPoints() { ? ? ? ? width = getWidth(); ? ? ? ? height = getHeight(); ? ? ? ? if (width > height) { ? ? ? ? ? ? offstartX = (width - height) / 2; ? ? ? ? ? ? width = height; ? ? ? ? }else{ ? ? ? ? ? ? offstartY = (height - width) / 2; ? ? ? ? ? ? height = width; ? ? ? ? } ? ? ? ? bitmap_normal = BitmapFactory.decodeResource(getResources(), R.mipmap.normal); ? ? ? ? bitmap_pressed = BitmapFactory.decodeResource(getResources(), R.mipmap.press); ? ? ? ? bitmap_error = BitmapFactory.decodeResource(getResources(), R.mipmap.error); ? ? ? ? bitmap_line = BitmapFactory.decodeResource(getResources(), R.mipmap.line_normal); ? ? ? ? bitmap_line_error = BitmapFactory.decodeResource(getResources(), R.mipmap.line_error); ? ? ? ? points[0][0] = new Point(offstartX + width / 4,offstartY + height / 4); ? ? ? ? points[0][1] = new Point(offstartX + width / 2,offstartY + height / 4); ? ? ? ? points[0][2] = new Point(offstartX + width - width / 4,offstartY + height / 4); ? ? ? ? points[1][0] = new Point(offstartX + width / 4,offstartY + width / 2); ? ? ? ? points[1][1] = new Point(offstartX + width / 2,offstartY + width / 2); ? ? ? ? points[1][2] = new Point(offstartX + width - width / 4,offstartY + width / 2); ? ? ? ? points[2][0] = new Point(offstartX + width / 4,offstartY + width - width / 4); ? ? ? ? points[2][1] = new Point(offstartX + width / 2,offstartY + width - width / 4); ? ? ? ? points[2][2] = new Point(offstartX + width - width / 4,offstartY + width - width / 4); ? ? ? ? isInit = true; ? ? } ? ? @Override ? ? public 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) { ? ? ? ? ? ? ? ? isSelect = 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) { ? ? ? ? ? ? ? ? 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; ? ? } ? ? /** ? ? ?* @param point ? ? ?* @return ? ? ?*/ ? ? private boolean crossPoint(Point point){ ? ? ? ? if (pointList.contains(point)) { ? ? ? ? ? ? return true; ? ? ? ? }else{ ? ? ? ? ? ? return false; ? ? ? ? } ? ? } ? ? /** ? ? ?*/ ? ? public void resetPoint(){ ? ? ? ? for (int i = 0; i < pointList.size(); i++) { ? ? ? ? ? ? Point point = pointList.get(i); ? ? ? ? ? ? point.state = Point.STATE_NORMAL; ? ? ? ? } ? ? ? ? pointList.clear(); ? ? } ? ? /** ? ? ?*/ ? ? public void errorPoint(){ ? ? ? ? for (Point point : pointList) { ? ? ? ? ? ? point.state = Point.STATE_ERROR; ? ? ? ? } ? ? } ? ? /** ? ? ?* @return ? ? ?*/ ? ? 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; ? ? } ? ? 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; ? ? ? ? } ? ? ? ? /** ? ? ? ? ?* @param a ? ? ? ? ?* @param b ? ? ? ? ?* @return ? ? ? ? ?*/ ? ? ? ? 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)) ; ? ? ? ? } ? ? ? ? /** ? ? ? ? ?*? ? ? ? ? ?* @param paintX ? ? ? ? ?* @param pointY ? ? ? ? ?* @param r ? ? ? ? ?* @param moveX ? ? ? ? ?* @param moveY ? ? ? ? ?* @return ? ? ? ? ?*/ ? ? ? ? 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 ; ? ? ? ? } ? ? } }
2. 第二步
编写布局文件activity_main.xml,在主布局文件中引入自定义的View。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout ? ? xmlns:android="http://schemas.android.com/apk/res/android" ? ? xmlns:app="http://schemas.android.com/apk/res-auto" ? ? xmlns:tools="http://schemas.android.com/tools" ? ? android:layout_width="match_parent" ? ? android:layout_height="match_parent"> ? ? <com.newdegree.mylock.LockPatterView ? ? ? ? android:layout_width="match_parent" ? ? ? ? android:layout_height="wrap_content"/> </RelativeLayout>
最后,运行程序就能看到九宫格图案了。
总结:这样我们就完成了九宫格图案解锁的开发,我们可以在自己完成的程序中绘制各种解锁图案。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。
相关文章
Android编程实现读取手机联系人、拨号、发送短信及长按菜单操作方法实例小结
这篇文章主要介绍了Android编程实现读取手机联系人、拨号、发送短信及长按菜单操作方法,以完整实例形式总结分析了Android编程实现读取手机联系人、拨号、发送短信及长按菜单等操作的相关技巧,需要的朋友可以参考下2015-10-10android中在Activity中响应ListView内部按钮的点击事件的两种方法
本篇文章主要介绍了android中在Activity中响应ListView内部按钮的点击事件的两种方法,有需要的可以了解一下。2016-11-11Android开发笔记之:一分钟学会使用Logcat调试程序的详解
本篇文章是对Android中Logcat调试程序的使用进行了详细的分析介绍,需要的朋友参考下2013-05-05Android 6.0 蓝牙搜索不到设备原因,MIUI权限申请机制方法
今天小编就为大家分享一篇Android6.0 蓝牙搜索不到设备原因,MIUI权限申请机制方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧2018-07-07Flutter使用texture_rgba_renderer实现桌面端渲染视频详解
这篇文章主要为大家介绍了Flutter如何使用texture_rgba_renderer实现桌面端渲染视频,文中的示例代码讲解详细,需要的可以了解一下2023-07-07Android编程实现canvas绘制柱状统计图功能【自动计算宽高及分度值、可左右滑动】
这篇文章主要介绍了Android编程实现canvas绘制柱状统计图功能,具备自动计算宽高及分度值及左右滑动的功能,涉及Android canvas绘图操作相关技巧,需要的朋友可以参考下2017-01-01Android实现SwipeRefreshLayout首次进入自动刷新
这篇文章主要为大家详细介绍了Android实现SwipeRefreshLayout首次进入自动刷新,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2017-01-01
最新评论