Android自定义PasswordInputView密码输入

所属分类: 软件编程 / Android 阅读数: 87
收藏 0 赞 0 分享

欢迎来到“实现自定义密码输入控件”这一章节,PasswordInputView定义了密码输入的监听,支持直接在布局文件定义属性值、支持直接获取密码输入的长度、原始密码……

先上图

PasswordInputView是做什么的?

PasswordInputView是一个自定义密码输入的控件,类似支付宝、微信支付的密码输入,同时定义了密码输入的监听,支持直接在布局文件定义属性值、支持直接获取密码输入的长度、原始密码等,还可以扩展其他方法,请自行实现。

实现原理

1.创建一个类 ‘PasswordInputView' ,让其继承EditText,因为我们要实现的自定义view是用来密码输入的,所以必须继承EditText。

2.为了在布局(layout)文件(.xml)能直接定义PasswordInputView各个属性的值,我们需要定义PasswordInputView带AttributeSet 参数的构造方法。

public PasswordInputView(Context context, AttributeSet attr) {
  super(context, attr);
  init(context, attr);
}

3.在'value/attrs.xml'中定义PasswordInputView各个属性及其类型,如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <declare-styleable name="Passwordinputview">
    <attr name="passwordLength" format="integer"/>
    <attr name="borderWidth" format="dimension"/>
    <attr name="borderRadius" format="dimension"/>
    <attr name="borderColor" format="color"/>
    <attr name="passwordWidth" format="dimension"/>
    <attr name="passwordColor" format="color"/>
  </declare-styleable>
</resources>

4.重载OnDraw(Canvas canvas)方法,并在其实现画边框、画内容区域(以填充模式绘制Paint.Style.FILL)、画分割线、画实心圆点(密码)。有人可能会问:画了边框、分割线,就可以了,为什么还要画内容区域?问得好,笔者在实现过程中也碰到这个问题,当时没有画内容区域,导致输入的原始内容也显示出来了(如下异常图),所以画内容区域(以填充模式绘制Paint.Style.FILL)是为了掩盖原始内容不被发现,切记必不可少。

正确代码如下:

 private void init(Context context, AttributeSet attr) {
  TypedArray ta = context.obtainStyledAttributes(attr, R.styleable.Passwordinputview);
  try {
   passwordLength = ta.getInt(R.styleable.Passwordinputview_passwordLength, passwordLength);
   borderWidth = ta.getDimensionPixelSize(R.styleable.Passwordinputview_borderWidth, borderWidth);
   borderRadius = ta.getDimensionPixelSize(R.styleable.Passwordinputview_borderRadius, borderRadius);
   borderColor = ta.getColor(R.styleable.Passwordinputview_borderColor, borderColor);
   passwordWidth = ta.getDimensionPixelSize(R.styleable.Passwordinputview_passwordWidth, passwordWidth);
   passwordColor = ta.getColor(R.styleable.Passwordinputview_passwordColor, passwordColor);
  } catch (Exception e) {

  }
  ta.recycle();

  borderPaint = new Paint();
  borderPaint.setAntiAlias(true);
  borderPaint.setColor(borderColor);
  borderPaint.setStrokeWidth(borderWidth);
  borderPaint.setStyle(Paint.Style.FILL); //以填充模式来画,防止原始输入内容显示出来

  passwordPaint = new Paint();
  passwordPaint.setAntiAlias(true);
  passwordPaint.setColor(passwordColor);
  passwordPaint.setStrokeWidth(passwordWidth);
 }

 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  int width = getWidth();
  int height = getHeight();

  //画边框
  RectF rect = new RectF(0, 0, width, height);
  borderPaint.setColor(borderColor);
  canvas.drawRoundRect(rect, borderRadius, borderRadius, borderPaint);

  //画内容区域,与上面的borderPaint.setStyle(Paint.Style.FILL)对应, 防止原始输入内容显示出来
  RectF rectContent = new RectF(rect.left + defaultContentMargin, rect.top + defaultContentMargin, rect.right - defaultContentMargin, rect.bottom - defaultContentMargin);
  borderPaint.setColor(Color.WHITE);
  canvas.drawRoundRect(rectContent, borderRadius, borderRadius, borderPaint);

  //画分割线:分割线数量比密码数少1
  borderPaint.setColor(borderColor);
  borderPaint.setStrokeWidth(defaultSplitLineWidth);
  for (int i = 1; i < passwordLength; i++) {
   float x = width * i / passwordLength;
   canvas.drawLine(x, 0, x, height, borderPaint);
  }

  //画密码内容
  float px, py = height / 2;
  float halfWidth = width / passwordLength / 2;
  for (int i = 0; i < textLength; i++) {
   px = width * i / passwordLength + halfWidth;
   canvas.drawCircle(px, py, passwordWidth, passwordPaint);
  }
}

5.定义“设置属性值”的方法,如下

public void setBorderWidth(int borderWidth) {
 this.borderWidth = borderWidth;
 borderPaint.setStrokeWidth(borderWidth);
 postInvalidate();
}

动态图

项目源码

点此链接

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

更多精彩内容其他人还在看

Android网络编程之获取网络上的Json数据实例

这篇文章主要介绍了Android网络编程之获取网络上的Json数据实例,本文用完整的代码实例讲解了在Android中读取网络中Json数据的方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中的windowSoftInputMode属性详解

这篇文章主要介绍了Android中的windowSoftInputMode属性详解,本文对windowSoftInputMode的9个属性做了详细总结,需要的朋友可以参考下
收藏 0 赞 0 分享

Android网络编程之UDP通信模型实例

这篇文章主要介绍了Android网络编程之UDP通信模型实例,本文给出了服务端代码和客户端代码,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中使用ListView实现漂亮的表格效果

这篇文章主要介绍了Android中使用ListView实现漂亮的表格效果,本文用详细的代码实例创建了一个股票行情表格,需要的朋友可以参考下
收藏 0 赞 0 分享

Android中刷新界面的二种方法

这篇文章主要介绍了Android中刷新界面的二种方法,本文使用Handler、postInvalidate两种方法实现界面刷新,需要的朋友可以参考下
收藏 0 赞 0 分享

Android SDK三种更新失败及其解决方法

这篇文章主要介绍了Android SDK三种更新失败及其解决方法,需要的朋友可以参考下
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(一)

Android3.0(API level 11)开始,Android设备不再需要专门的菜单键。随着这种变化,Android app应该取消对传统6项菜单的依赖。取而代之的是提供anction bar来提供基本的用户功能
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(二)

这次将继续上一篇文章没有讲完的Menu的学习,上下文菜单(Context menu)和弹出菜单(Popup menu)
收藏 0 赞 0 分享

Android学习笔记——Menu介绍(三)

今天继续昨天没有讲完的Menu的学习,主要是Popup Menu的学习,需要的朋友可以参考下
收藏 0 赞 0 分享

Android显示网络图片实例

这篇文章主要介绍了Android显示网络图片的方法,以实例形式展示了Android程序显示网络图片的方法,非常具有实用价值,需要的朋友可以参考下
收藏 0 赞 0 分享
查看更多