我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Android APP数字解锁实例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Android APP数字解锁实例详解

Android APP数字上锁

最近抽时间做了下数字解锁的功能,手机有数字解锁,App也可以做到,避免某些应用隐私泄漏,一下就是实现效果图:

序言:这两天老大给了个任务,说是做一个仿ios的数字锁屏界面,心想着这种东西网上应该有挺多的,然后就先百度了一把,谁知道案例好像少的可怜,然后带着怀疑的心态去下载了千辛万苦找到的“源码”,看里面写的,然后自己有点眉目了,就自己借着“源码”的思路自己实现了一把,见上图。

思路:

这里我们可以看成两部分,一部分是上面的输入的,另一部分是底部的按键。
先来看上面那部分,我们可以看成是TextView,然后响应下面按键的动作。下面这部分,图中的每个按钮都需要自己画出来,难点就是根据第一个按键的坐标(第一个坐标我们初始化)算出每个按键的坐标,然后根据手指的触摸屏事件来判断点击的是哪个按键

接下来我们来看核心代码:

输入框部分:


public class PasswordTextView extends TextView{
 private final String sing = "*";//密文显示的内容
 private String content = "";//显示的内容
 //文本改变事件回调接口
 private OnTextChangedListener onTextChangedListener;
 
 private Handler handler = new Handler(){
  public void handleMessage(android.os.Message msg) {
   //密文显示
   PasswordTextView.this.setText(sing);
   //回调改变事件接口
   if(onTextChangedListener != null){
    onTextChangedListener.textChanged(content);
   }
  };
 };
 
 public PasswordTextView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 
 public void setOnTextChangedListener(OnTextChangedListener onTextChangedListener){
  this.onTextChangedListener = onTextChangedListener;
 }
 
 public void setTextContent(String text){
  //获得输入的内容
  this.content = text;
  if(!TextUtils.isEmpty(text)){
   handler.sendEmptyMessage(0);//向Handler发送消息
  }else{
   this.setText("");
  }
 }
 
 public String getTextContent(){
  return content;
 }
 
 public interface OnTextChangedListener{
  
  public void textChanged(String content);
 }
}

下面按键部分


public class NumericK eyboard extends View {
 private int screen_width = 0;// 屏幕的宽度
 private float first_x = 0;// 绘制1的x坐标
 private float first_y = 0;// 绘制1的y坐标
 private float[] xs = new float[3];//声明数组保存每一列的圆心横坐标
 private float[] ys = new float[4];//声明数组保存每一排的圆心纵坐标
 private float circle_x, circle_y;//点击处的圆心坐标
 private int number = -1;//点击的数字
 private OnNumberClick onNumberClick;//数字点击事件
 
 private int type = -1;
 
 public NumericKeyboard(Context context) {
  super(context);
  initData(context);// 初始化数据
 }
 public NumericKeyboard(Context context, AttributeSet attrs) {
  super(context, attrs);
  initData(context);// 初始化数据
 }
 
 public void setOnNumberClick(OnNumberClick onNumberClick) {
  this.onNumberClick = onNumberClick;
 }
 // 初始化数据
 private void initData(Context context) {
  // 获取屏幕的宽度
  screen_width = SystemUtils.getSystemDisplay(context)[0];
  // 获取绘制1的x坐标
  first_x = screen_width / 4;
  // 获取绘制1的y坐标
  first_y = (SystemUtils.getSystemDisplay(context)[1] - SystemUtils.getSystemDisplay(context)[1] / 3) / 4;
  //添加每一排的横坐标
  xs[0] = first_x + 10;
  xs[1] = first_x * 2 + 10;
  xs[2] = first_x * 3 + 10;
  //添加每一列的纵坐标
  ys[0] = 40 + first_y - 15;
  ys[1] = 40 + first_y + first_x - 15;
  ys[2] = 40 + first_y + first_x * 2 - 15;
  ys[3] = 40 + first_y + first_x * 3 - 15;
 }
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  // 创建画笔对象
  Paint paint = new Paint();
  paint.setColor(Color.BLACK);// 设置画笔颜色
  paint.setTextSize(40);// 设置字体大小
  paint.setStrokeWidth(2);
  // 绘制文本,注意是从坐标开始往上绘制
  // 这里较难的就是算坐标
  // 绘制第一排1,2,3
  canvas.drawText("1", first_x, 40 + first_y, paint);
  canvas.drawText("2", first_x * 2, 40 + first_y, paint);
  canvas.drawText("3", first_x * 3, 40 + first_y, paint);
  // 绘制第2排4,5,6
  canvas.drawText("4", first_x, 40 + first_y + first_x, paint);
  canvas.drawText("5", first_x * 2, 40 + first_y + first_x, paint);
  canvas.drawText("6", first_x * 3, 40 + first_y + first_x, paint);
  // 绘制第3排7,8,9
  canvas.drawText("7", first_x, 40 + first_y + first_x * 2, paint);
  canvas.drawText("8", first_x * 2, 40 + first_y + first_x * 2, paint);
  canvas.drawText("9", first_x * 3, 40 + first_y + first_x * 2, paint);
  // 绘制第4排0
  canvas.drawText("0", first_x * 2, 40 + first_y + first_x * 3, paint);
  //为每一个数字绘制一个圆
  paint.setColor(Color.WHITE);//设置画笔颜色
  paint.setAntiAlias(true);//设置抗锯齿
  //设置绘制空心圆
  paint.setStyle(Paint.Style.STROKE);
  //依次绘制第一排的圆
  canvas.drawCircle(first_x + 10, 40 + first_y - 15, 70, paint);
  canvas.drawCircle(first_x * 2 + 10, 40 + first_y - 15, 70, paint);
  canvas.drawCircle(first_x * 3 + 10, 40 + first_y - 15, 70, paint);
  //依次绘制第2排的圆
  canvas.drawCircle(first_x + 10, 40 + first_y + first_x - 15, 70, paint);
  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x - 15, 70, paint);
  canvas.drawCircle(first_x * 3 + 10, 40 + first_y + first_x - 15, 70, paint);
  //依次绘制第3排的圆
  canvas.drawCircle(first_x + 10, 40 + first_y + first_x * 2 - 15, 70, paint);
  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x * 2 - 15, 70, paint);
  canvas.drawCircle(first_x * 3 + 10, 40 + first_y + first_x * 2 - 15, 70, paint);
  //绘制最后一个圆
  canvas.drawCircle(first_x * 2 + 10, 40 + first_y + first_x * 3 - 15, 70, paint);
  //判断是否点击数字(点击数字产生的渐变效果)
  if (circle_x > 0 && circle_y > 0) {
   if (type == 0) {//按下刷新
    paint.setColor(Color.WHITE);//设置画笔颜色
    paint.setStyle(Paint.Style.FILL_AND_STROKE);//按下的时候绘制实心圆
    canvas.drawCircle(circle_x, circle_y, 70, paint);//绘制圆
   } else if (type == 1) {//弹起刷新
    paint.setColor(Color.WHITE);//设置画笔颜色
    paint.setStyle(Paint.Style.STROKE);//弹起的时候再绘制空心圆
    canvas.drawCircle(circle_x, circle_y, 70, paint);//绘制圆
    //绘制完成后,重置
    circle_x = 0;
    circle_y = 0;
   }
  }
 }
 
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  //事件判断
  switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN://按下
    //判断点击的坐标位置
    float x = event.getX();//按下时的X坐标
    float y = event.getY();//按下时的Y坐标
    //判断点击的是哪一个数字圆
    handleDown(x, y);
    return true;
   case MotionEvent.ACTION_UP://弹起
    type = 1;//弹起刷新
    invalidate();//刷新界面
    //返回点击的数字
    if (onNumberClick != null && number != -1) {
     onNumberClick.onNumberReturn(number);
    }
    setDefault();//恢复默认
    //发送辅助事件
    sendAccessEvent(R.string.numeric_keyboard_up);
    return true;
   case MotionEvent.ACTION_CANCEL://取消
    //恢复默认值
    setDefault();
    return true;
  }
  return false;
 }
 
 private void setDefault() {
  circle_x = 0;
  circle_y = 0;
  type = -1;
  number = -1;
  sendAccessEvent(R.string.numeric_keyboard_cancel);
 }
 
 private void sendAccessEvent(int resId) {
  //设置描述
  setContentDescription(getContext().getString(resId));
  //发送辅助事件
  sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
  setContentDescription(null);
 }
 
 private void handleDown(float x, float y) {
  //判断点击的是那一列的数据
  if (xs[0] - 70 <= x && x <= xs[0] + 70) {//第一列
   //获取点击处的圆心横坐标
   circle_x = xs[0];
   //判断点击的是哪一排
   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[0];
    number = 1;//设置点击的数字
   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[1];
    number = 4;//设置点击的数字
   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[2];
    number = 7;//设置点击的数字
   }
  } else if (xs[1] - 70 <= x && x <= xs[1] + 70) {//第2列
   //获取点击处的圆心横坐标
   circle_x = xs[1];
   //判断点击的是哪一排
   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[0];
    number = 2;//设置点击的数字
   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[1];
    number = 5;//设置点击的数字
   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[2];
    number = 8;//设置点击的数字
   } else if (ys[3] - 70 <= y && ys[3] + 70 >= y) {//第4排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[3];
    number = 0;//设置点击的数字
   }
  } else if (xs[2] - 70 <= x && x <= xs[2] + 70) {//第3列
   //获取点击处的圆心横坐标
   circle_x = xs[2];
   //判断点击的是哪一排
   if (ys[0] - 70 <= y && ys[0] + 70 >= y) {//第1排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[0];
    number = 3;//设置点击的数字
   } else if (ys[1] - 70 <= y && ys[1] + 70 >= y) {//第2排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[1];
    number = 6;//设置点击的数字
   } else if (ys[2] - 70 <= y && ys[2] + 70 >= y) {//第3排
    //获取点击的数字圆的圆心纵坐标
    circle_y = ys[2];
    number = 9;//设置点击的数字
   }
  }
  sendAccessEvent(R.string.numeric_keyboard_down);
  type = 0;//按下刷新
  //绘制点击时的背景圆
  invalidate();
 }
 
 public interface OnNumberClick {
  
  public void onNumberReturn(int number);
 }
}

上面说了,难点在于计算按键的位置,在这里我是根据我下载的demo里面的计算方式相应的修改了,如果不明白android屏幕坐标系的同学请看下面的文章:

参考:

android坐标系详解

Github下载地址:DEMO下载

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

您可能感兴趣的文章:Android唤醒、解锁屏幕代码实例android 九宫格滑动解锁开机实例源码学习android滑动解锁震动效果的开启和取消Android实现九宫格解锁的方法轻松实现Android自定义九宫格图案解锁Android指纹解锁方法解析Android手机屏幕敲击解锁功能代码Android指纹解锁示例代码轻松实现安卓(Android)九宫格解锁Android仿手机QQ图案解锁功能


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Android APP数字解锁实例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Android APP数字解锁实例详解

Android APP数字上锁 最近抽时间做了下数字解锁的功能,手机有数字解锁,App也可以做到,避免某些应用隐私泄漏,一下就是实现效果图:序言:这两天老大给了个任务,说是做一个仿ios的数字锁屏界面,心想着这种东西网上应该有挺多的,然后就
2022-06-06

Android应用App更新实例详解

前言:现在一般的Android软件都是需要不断更新的,当你打开某个app的时候,如果有新的版本,它会提示你有新版本需要更新。该项目实现的就是这个功能。并且有强制更新和更新提示两种方式,当有更新时,会弹出一个提示框,点击下载,则在通知来创建一
2022-06-06

android app进行代码混淆实例详解

接到一个新的任务,对现有项目进行代码混淆。之前对混淆有过一些了解,但是不够详细和完整,知道有些东西混淆起来还是比较棘手的。不过幸好目前的项目不是太复杂(针对混淆这块来说),提前完成~~现总结之。 第一部分 介绍下操作流程(eclipse)
2022-06-06

Android App增量更新详解及实例代码

Android App增量更新实例--Smart App Updates 介绍你所看到的,是一个用于Android应用程序增量更新的开源库。包括客户端、服务端两部分代码。原理自从 Android 4.1 开始,Google引入
2022-06-06

Express框架详解app函数使用实例

这篇文章主要为大家介绍了Express框架app函数使用实例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-03

Android startActivityForResult实例详解

Android startActivityForResult实例详解startActivityForResult用于两个activity之间的数据传递,Activity1传值给Activity2,Activity2再返回值给Activity
2023-05-31

Android获取arrays.xml里的数组字段值实例详解

Android获取arrays.xml里的数组字段值实例详解 比如在arrays.xml里: Re
2022-06-06

uni-app网络请求、数据缓存实例详解

这篇文章主要介绍了uni-app网络请求、数据缓存的相关知识,本文通过实例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
2022-11-16

Android UI:ListView - SimpleAdapter实例详解

Android UI:ListView -- SimpleAdapter SimpleAdapter是扩展性最好的适配器,可以定义各种你想要的布局,而且使用很方便。layout :2022-06-06

Android ProgressDialog的实例详解

Android ProgressDialog的实例详解当自己做一些耗时操作时,希望给用户一些提示信息,告诉用户正在进行耗时操作,这时就可以用到ProgressDialog。1.新建一个全局变量ProgressDialogprivate Pr
2023-05-30

Android json数据解析详解及实例代码

Android json数据解析详解 移动开发经常要与服务器数据交互,也常使用json数据格式,那就说说Android json解析。1.最简单json格式解析如下://解析json ry { JSONTokener jsonPa
2022-06-06

android之App Widget开发实例代码解析

Android Widget开发案例实现是本文要介绍的内容,主要是来了解并学习Android Widget开发应用,今天我们要写一下Android Widget的开发,由于快点凌晨,我就不说的太具体了,同志们就模仿吧! 首先继续了解下App
2022-06-06

Android 文件数据存储实例详解

Android之文件数据存储 一、文件保存数据介绍 Activity提供了openFileOutput()方法可以用于把数据输出到文件中,具体的实现过程与在J2SE环境中保存数据到文件中是一样的。文件可用来存放大量数据,如文本、图书、音频等
2022-06-06

Android中系统自带锁WalkLock与KeyguardLock用法实例详解

本文实例讲述了Android中系统自带锁WalkLock与KeyguardLock用法。分享给大家供大家参考,具体如下: WalkLock - 顾名思义 唤醒锁 点亮屏幕用的 KeyguardLock - 顾名思义 键盘锁 解锁键盘用的 详
2022-06-06

Android唤醒、解锁屏幕代码实例

解锁、唤醒屏幕用到KeyguardManager,KeyguardLock,PowerManager,PowerManager.WakeLock 所需权限:代码如下: 2022-06-06

Android实现屏幕锁定源码详解

最近有朋友问屏幕锁定的问题,自己也在学习,网上找了下也没太详细的例子,看的资料书上也没有有关屏幕锁定程序的介绍,下个小决心,自己照着官方文档学习下,现在做好了,废话不多说,先发下截图,看下效果,需要注意的地方会加注释,有问题的朋友可以直接留
2022-06-06

Android Dialog 动画实例详解

Android Dialog 动画实例详解 动画描述: 动画与底部菜单一样出现和消失 制作过程: 1. 创建两个动画文件 window_in.xml:
2022-06-06

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录