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

Android自定义View实现随机验证码

这篇文章主要介绍了Android自定义View实现随机验证码的相关资料,感兴趣的小伙伴们可以参考一下

对于android开发来说自定义View还是一个比较重要的技能,所以在这里写一篇自定义View入门的文章,也是实现一个相对简单的随机产生验证码的功能:
自定义View主要也就分为几步
 1.自定义View的属性
 2.在我们的自定义的布局中获取自定义属性
 3.重写onMesure方法
 4.重写onDraw方法
好现在我们就一步一步的来,首先创建我们的View属性
在valuse目录下创建一个attrs.xml的文件,然后:

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

 
 
 

 
 
 
 
 


我们总共定义了三个属性,一个是颜色,内容,大小

然后我们去建立我们的自定义类

public class VerificationCodeView extends View {
 /**
 * 文本
 */
 private String mTitleText;
 /**
 * 文本的颜色
 */
 private int mTextColor;
 /**
 * 文本的大小
 */
 private int mTextSize;

 /**
 * 绘制时控制文本绘制的范围
 */
 private Rect mBound;
 /**
 * 初始化画笔
 */
 private Paint mTextPaint;
 private Paint mPointPaint;
 private Paint mPathPaint;
 /**
 * 干扰点坐标的集合
 */
 private ArrayList mPoints = new ArrayList();
 /**
 * 绘制贝塞尔曲线的路径集合
 */
 private ArrayList mPaths = new ArrayList();

 public VerificationCodeView(Context context) {
 this(context, null);
 }

 public VerificationCodeView(Context context, AttributeSet attributeSet) {
 this(context, attributeSet, 0);
 }

 public VerificationCodeView(Context context, AttributeSet attributeSet, int defStyle) {
 super(context, attributeSet, defStyle);
 TypedArray typedArray = context.getTheme().obtainStyledAttributes(attributeSet, R.styleable.VerificationCodeView, defStyle, 0);
 int size = typedArray.getIndexCount();
 for (int i = 0; i  set = new HashSet();
 while (set.size() <4) {
  int randomInt = random.nextInt(10);
  set.add(randomInt);
 }
 StringBuffer sb = new StringBuffer();
 for (Integer i : set) {
  sb.append("" + i);
 }

 return sb.toString();
 }
}

以上代码就是自定义的类,继承了View他有三个构造方法,我们要获取它的属性,所以一定要走第三个,但是默认是第二个,所以我们要在每一个里面调用第三个,以确保做了初始化工作 注意调用的时候用的是this的构造方法,而不是super
当我们的这个类出来之后,后面的就很简单了

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


 


在布局里面应用它就可以了, xmlns:verification=”http://schemas.android.com/apk/res-auto”是必须要的,要不找不到自定义的属性。

好了到这为止就实现了最简单的

接下来我们就是实现绘制一些散点和曲线,修改我们的自定义类的onDraw()方法

@Override
 protected void onDraw(Canvas canvas) {
 initData();
 Random mRandom = new Random();
 //生成随机的背景颜色
 mTextPaint.setARGB(255, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20);
 canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mTextPaint);
 //生成随机的文字颜色
 mTextPaint.setARGB(255, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20);
 //将文字画在布局的中间
 canvas.drawText(mTitleText, getWidth() / 2 - mBound.width() / 2, getHeight() / 2 + mBound.height() / 2, mTextPaint);

 // 产生干扰效果1 -- 干扰点
 for (PointF pointF : mPoints) {
  mPointPaint.setARGB(255, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20);
  canvas.drawPoint(pointF.x, pointF.y, mPointPaint);
 }
 // 产生干扰效果2 -- 干扰线
 for (Path path : mPaths) {
  mPathPaint.setARGB(255, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20, mRandom.nextInt(200) + 20);
  canvas.drawPath(path, mPathPaint);
 }

 private void initData() {
 Random mRandom = new Random();
 // 获取控件的宽和高,此时已经测量完成
 int mHeight = getHeight();
 int mWidth = getWidth();
 mPoints.clear();
 // 生成干扰点坐标
 for (int i = 0; i <150; i++) {
  PointF pointF = new PointF(mRandom.nextInt(mWidth) + 10, mRandom.nextInt(mHeight) + 10);
  mPoints.add(pointF);
 }
 mPaths.clear();
 // 生成干扰线坐标
 for (int i = 0; i <2; i++) {
  Path path = new Path();
  int startX = mRandom.nextInt(mWidth / 3) + 10;
  int startY = mRandom.nextInt(mHeight / 3) + 10;
  int endX = mRandom.nextInt(mWidth / 2) + mWidth / 2 - 10;
  int endY = mRandom.nextInt(mHeight / 2) + mHeight / 2 - 10;
  path.moveTo(startX, startY);
  path.quadTo(Math.abs(endX - startX) / 2, Math.abs(endY - startY) / 2, endX, endY);
  mPaths.add(path);
 }
 }

 private void init() {
 // 初始化文字画笔
 /**
  * 获得绘制文本的宽和高
  */
 mTextPaint = new Paint();
 mTextPaint.setTextSize(mTextSize);

 mBound = new Rect();
 //获取到的存在mBound里面
 mTextPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);
 // 初始化干扰点画笔
 mPointPaint = new Paint();
 mPointPaint.setStrokeWidth(6);
 mPointPaint.setStrokeCap(Paint.Cap.ROUND); // 设置断点处为圆形
 // 初始化干扰线画笔
 mPathPaint = new Paint();
 mPathPaint.setStrokeWidth(5);
 mPathPaint.setColor(Color.GRAY);
 mPathPaint.setStyle(Paint.Style.STROKE); // 设置画笔为空心
 mPathPaint.setStrokeCap(Paint.Cap.ROUND); // 设置断点处为圆形
 }

init()方法请自行加在构造方法里面
OK到这为止就完成了,以后我们用到只要移植就可以了,怎么样,也很简单吧

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


推荐阅读
  • 通过自定义 `TextView`,实现了在用户点击或焦点变化时动态调整字体颜色的效果。该方法利用了 `ColorStateList` 和 `Selector` 资源文件,确保了界面交互的流畅性和视觉效果的提升。具体实现中,通过重写 `onTouchEvent` 和 `onFocusChanged` 方法,精确控制了颜色变化的时机和状态。此外,还对性能进行了优化,确保在高频率操作下依然保持高效响应。 ... [详细]
  • 解决基于XML配置的MyBatis在Spring整合中出现“无效绑定语句(未找到):com.music.dao.MusicDao.findAll”问题的方法
    在将Spring与MyBatis进行整合时,作者遇到了“无效绑定语句(未找到):com.music.dao.MusicDao.findAll”的问题。该问题主要出现在使用XML文件配置DAO层的情况下,而注解方式配置则未出现类似问题。作者详细分析了两个配置文件之间的差异,并最终找到了解决方案。本文将详细介绍问题的原因及解决方法,帮助读者避免类似问题的发生。 ... [详细]
  • Android 图像色彩处理技术详解
    本文详细探讨了 Android 平台上的图像色彩处理技术,重点介绍了如何通过模仿美图秀秀的交互方式,利用 SeekBar 实现对图片颜色的精细调整。文章展示了具体的布局设计和代码实现,帮助开发者更好地理解和应用图像处理技术。 ... [详细]
  • 本文探讨了在Android应用中实现动态滚动文本显示控件的优化方法。通过详细分析焦点管理机制,特别是通过设置返回值为`true`来确保焦点不会被其他控件抢占,从而提升滚动文本的流畅性和用户体验。具体实现中,对`MarqueeText.java`进行了代码层面的优化,增强了控件的稳定性和兼容性。 ... [详细]
  • 当前,众多初创企业对全栈工程师的需求日益增长,但市场中却存在大量所谓的“伪全栈工程师”,尤其是那些仅掌握了Node.js技能的前端开发人员。本文旨在深入探讨全栈工程师在现代技术生态中的真实角色与价值,澄清对这一角色的误解,并强调真正的全栈工程师应具备全面的技术栈和综合解决问题的能力。 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • 本文深入探讨了 iOS 开发中 `int`、`NSInteger`、`NSUInteger` 和 `NSNumber` 的应用与区别。首先,我们将详细介绍 `NSNumber` 类型,该类用于封装基本数据类型,如整数、浮点数等,使其能够在 Objective-C 的集合类中使用。通过分析这些类型的特性和应用场景,帮助开发者更好地理解和选择合适的数据类型,提高代码的健壮性和可维护性。苹果官方文档提供了更多详细信息,可供进一步参考。 ... [详细]
  • 本文深入解析了 Apache 配置文件 `httpd.conf` 和 `.htaccess` 的优化方法,探讨了如何通过合理配置提升服务器性能和安全性。文章详细介绍了这两个文件的关键参数及其作用,并提供了实际应用中的最佳实践,帮助读者更好地理解和运用 Apache 配置。 ... [详细]
  • 在Linux环境下编译安装Heartbeat时,常遇到依赖库缺失的问题。为确保顺利安装,建议预先通过yum安装必要的开发库,如glib2-devel、libtool-ltdl-devel、net-snmp-devel、bzip2-devel和ncurses-devel等。这些库是编译过程中不可或缺的组件,能够有效避免编译错误,确保Heartbeat的稳定运行。 ... [详细]
  • 深入解析Tomcat:开发者的实用指南
    深入解析Tomcat:开发者的实用指南 ... [详细]
  • 如何在Java中高效构建WebService
    本文介绍了如何利用XFire框架在Java中高效构建WebService。XFire是一个轻量级、高性能的Java SOAP框架,能够简化WebService的开发流程。通过结合MyEclipse集成开发环境,开发者可以更便捷地进行项目配置和代码编写,从而提高开发效率。此外,文章还详细探讨了XFire的关键特性和最佳实践,为读者提供了实用的参考。 ... [详细]
  • 在处理大规模并发请求时,传统的多线程或多进程模型往往无法有效解决性能瓶颈问题。尽管它们在处理小规模任务时能提升效率,但在高并发场景下,系统资源的过度消耗和上下文切换的开销会显著降低整体性能。相比之下,Python 的 `asyncio` 模块通过协程提供了一种轻量级且高效的并发解决方案。本文将深入解析 `asyncio` 模块的原理及其在实际应用中的优化技巧,帮助开发者更好地利用协程技术提升程序性能。 ... [详细]
  • 可转债数据智能抓取与分析平台优化
    本项目旨在优化可转债数据的智能抓取与分析平台。通过爬取集思录上的可转债信息(排除已发布赎回的债券),并结合安道全教授提出的三条安全线投资策略,新增了建仓线、加仓线和重仓线,以提供更精准的投资建议。 ... [详细]
  • 如何构建基于Spring MVC框架的Java Web应用项目
    在构建基于Spring MVC框架的Java Web应用项目时,首先应创建一个新的动态Web项目。接着,需将必要的JAR包导入至WebContent/WEB-INF/lib目录下,确保包括Spring核心库及相关依赖。如遇缺失的JAR包,可向社区求助或通过Maven等工具自动下载。正确配置后,即可开始搭建应用结构与功能模块。 ... [详细]
  • 本文深入探讨了 HTML 中的 `margin` 属性,详细解析了其基本特性和应用场景。文章不仅介绍了 `margin` 的基本概念,还重点讨论了垂直外边距合并现象,并分析了 `margin` 在块级元素与内联元素中的不同表现。通过实例和代码示例,帮助读者全面理解 `margin` 的使用技巧和常见问题。 ... [详细]
author-avatar
小猪爱情守护者
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有