热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android自定义控件实现九宫格解锁功能

这篇文章主要为大家详细介绍了Android自定义控件实现九宫格解锁功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

最终Android九宫格解锁效果如下

1.进行定义实体point点

public class Point {
 private float x;
 private float y;
 //正常模式
 public static final int NORMAL_MODE = 1;
 //按下模式
 public static final int PRESSED_MODE = 2;
 //错误模式
 public static final int ERROR_MODE = 3;

 private int state = NORMAL_MODE;
 private String mark;

 public Point(float x, float y, String mark) {
  this.x = x;
  this.y = y;
  this.mark = mark;
 }

 public float getX() {
  return x;
 }

 public void setX(float x) {
  this.x = x;
 }

 public float getY() {
  return y;
 }

 public void setY(float y) {
  this.y = y;
 }

 public int getState() {
  return state;
 }

 public void setState(int state) {
  this.state = state;
 }

 public String getMark() {
  return mark;
 }

 public void setMark(String mark) {
  this.mark = mark;
 }
}

2.自定义ScreenLockView

public class ScreenLockView extends View {
 private static final String TAG = "ScreenLockView";

 // 错误格子的图片
 private Bitmap errorBitmap;
 // 正常格子的图片
 private Bitmap normalBitmap;
 // 手指按下时格子的图片
 private Bitmap pressedBitmap;
 // 错误时连线的图片
 private Bitmap lineErrorBitmap;
 // 手指按住时连线的图片
 private Bitmap linePressedBitmap;
 // 偏移量,使九宫格在屏幕中央
 private int offset;
 // 九宫格的九个格子是否已经初始化
 private boolean init;
 // 格子的半径
 private int radius;
 // 密码
 private String password = "123456";
 // 九个格子
 private Point[][] points = new Point[3][3];
 private int width;
 private int height;
 private Matrix matrix = new Matrix();
 private float moveX = -1;
 private float moveY = -1;
 // 是否手指在移动
 private boolean isMove;
 // 是否可以触摸,当用户抬起手指,划出九宫格的密码不正确时为不可触摸
 private boolean isTouch = true;
 // 用来存储记录被按下的点
 private List pressedPoint = new ArrayList<>();
 // 屏幕解锁监听器
 private OnScreenLockListener listener;

 public ScreenLockView(Context context) {
  super(context);
  init();
 }


 public ScreenLockView(Context context, AttributeSet attrs) {
  super(context, attrs);
  init();
 }

 public ScreenLockView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  init();
 }

 private void init() {
  errorBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_error);
  normalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_normal);
  pressedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bitmap_pressed);
  lineErrorBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.line_error);
  linePressedBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.line_pressed);
  radius = normalBitmap.getWidth() / 2;
 }

 @Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  super.onMeasure(widthMeasureSpec, heightMeasureSpec);
  int widthSize = MeasureSpec.getSize(widthMeasureSpec);
  int widthMode = MeasureSpec.getMode(widthMeasureSpec);
  int heightSize = MeasureSpec.getSize(heightMeasureSpec);
  int heightMode = MeasureSpec.getMode(heightMeasureSpec);
  if (widthSize > heightSize) {
   offset = (widthSize - heightSize) / 2;
  } else {
   offset = (heightSize - widthSize) / 2;
  }
  setMeasuredDimension(widthSize, heightSize);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  if (!init) {
   width = getWidth();
   height = getHeight();
   initPoint();
   init = true;
  }
  drawPoint(canvas);
  if (moveX != -1 && moveY != -1) {
   drawLine(canvas);
  }
 }

 // 画直线
 private void drawLine(Canvas canvas) {

  // 将pressedPoint中的所有格子依次遍历,互相连线
  for (int i = 0; i  0) {
      point = isPoint(x, y);
      if (point != null) {
       if (!crossPoint(point)) {
        point.setState(Point.PRESSED_MODE);
        pressedPoint.add(point);
       }
      }
      moveX = x;
      moveY = y;
      isMove = true;
     }
     break;
    case MotionEvent.ACTION_UP:
     isMove = false;
     String tempPwd = "";
     for (Point p : pressedPoint) {
      tempPwd += p.getMark();
     }
     if (listener != null) {
      listener.getStringPassword(tempPwd);
     }

     if (tempPwd.equals(password)) {
      if (listener != null) {
       listener.isPassword(true);
       this.postDelayed(runnable, 1000);
      }

     } else {
      for (Point p : pressedPoint) {
       p.setState(Point.ERROR_MODE);
      }
      isTouch = false;
      this.postDelayed(runnable, 1000);
      if (listener != null) {
       listener.isPassword(false);
      }
     }
     break;
   }
   invalidate();
  }
  return true;
 }

 private boolean crossPoint(Point point) {
  if (pressedPoint.contains(point)) {
   return true;
  }
  return false;
 }

 public interface OnScreenLockListener {
  public void getStringPassword(String password);

  public void isPassword(boolean flag);
 }

 public void setOnScreenLockListener(OnScreenLockListener listener) {
  this.listener = listener;
 }

 private Point isPoint(float x, float y) {
  Point point;
  for(int i = 0; i

3.RotateDegress类

public class RotateDegrees {
 public static float getDegrees(Point a, Point b){
  float degrees = 0 ;
  float aX = a.getX();
  float aY = a.getY();
  float bX = b.getX();
  float bY = b.getY();
  if(aX == bX){
   if(aYbX){
    if(aY>bY){
     degrees = 180 + (float)(Math.atan2(aY-bY,aX-bX)*180/Math.PI);
    }else{
     degrees = 180 - (float)(Math.atan2(bY -aY,aX - bX)*180/Math.PI);
    }

   }else{
    if(aY>bY){
     degrees = 360 -(float)(Math.atan2(aY - bY,bX-aX)*180/Math.PI);
    }else{
     degrees = (float)(Math.atan2(bY - aY,bX - aX)*180/Math.PI);
    }
   }
  }
  return degrees;
 }

 public static float getDegrees(Point a, float bX,float bY){
  Point b = new Point(bX,bY,null);
  return getDegrees(a,b);
 }
}

用到的图片资源

4.MainActivity中使用

public class MainActivity extends AppCompatActivity {

 private ScreenLockView screenLockView;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  screenLockView = (ScreenLockView) findViewById(R.id.slv);
  screenLockView.setOnScreenLockListener(new ScreenLockView.OnScreenLockListener() {
   @Override
   public void getStringPassword(String password) {

   }

   @Override
   public void isPassword(boolean flag) {
    String content;
    if (flag) {
     cOntent= "密码正确";

    } else {
     cOntent= "密码错误";
    }
    Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();

   }
  });
 }
}

5.布局文件

<&#63;xml version="1.0" encoding="utf-8"&#63;>


 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 前期部署1.JDK安装,配置PATH2.下载spark-1.6.1-bin-hadoop2.6.tgz,并上传到服务器解压3.在 usr 下创建软链接到目标文件夹4.修改配置文件, ... [详细]
  • 之前一直不明白package与install的区别,今天测试了下。如果b项目依赖a项目,而a打了包(package),jar仅仅时打到了a项目的target下。这时编译b项目,还是 ... [详细]
  • android anko,Anko for Android
    Anko是一个使开发Android应用更简单更快捷的库,Anko使你的代码简洁易懂,使开发者不用再在意AndroidSDK对Java版本的限制(目前还不支持Java8。).Anko ... [详细]
  • 图11、基本概念
    用邻接矩阵表示图:用 ... [详细]
  • 开始仔细学习WPF了说是动画不流畅,可以通过设置帧率解决,查了很多,都说设置Timeline.DesiredFrameRateProperty,但都没说加到哪里,在代码很多地方加上 ... [详细]
  • 系统被描述为不依赖于底层技术的服务服务通过消息实现1SOA涉及到服务的提供者和消费者参与SOA的系统是服务提供者,还是服务的消费者,要视工作流而定服务和消息是无状态的2服务和消费者 ... [详细]
  • 本文目录一览:1、哪有免费的JAVA教程?2、 ... [详细]
  • ThefileIhaveisabitunstructuredandmessy.Ihavefoo.xmlwhosesizeis100gbsfilesuchas: ... [详细]
  • 文档地址:https:github.comaxiosaxiosaxios理解和使用1.请求配置1{2请求服务器的URL3url:'user',45method创 ... [详细]
  • 开发笔记:Mavent——学Java不会Maven,怎么行
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Mavent——学Java不会Maven,怎么行相关的知识,希望对你有一定的参考价值。 ... [详细]
  • IOC是spring的核心技术之一。在spring中IOC(控制反转)就是由IOC容器来控制程序࿰ ... [详细]
  • Mybatis_04日志
    前几天临近期末考试,一直在准备考试,吐槽一下,这个学期的考试真是全背书,服了,背吐了。考完试到元旦又放肆了几天 ... [详细]
  • 用idea创建项目,默认是单模块项目的。如果一个项目比较大,包含多个子系统,可能会有一些公共的东西,独立出来, ... [详细]
  • AOP是Spring的核心,Spring不但自身对多种框架的集成是基于AOP,并且以非常方便的形式暴露给普通使用者。以前用AOP不多,主要是因为它以横截面的方式插入到主流程中,担心导致主流程代码 ... [详细]
  • 三步打造安全可靠的个人数据中心
    2009年了,网速更快了,上网的人更多了,病毒***也更猖獗了,我们装系统也装的更勤了,嘿嘿问题当然也更多了。 ... [详细]
author-avatar
Wobu想说
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有