Android自定义密码输入框——(仿支付宝等)
来源:互联网 发布:手机淘宝评价管理链接 编辑:程序博客网 时间:2024/06/01 10:33
Android自定义密码输入框,通过自定义输入显示框和自定义输入键盘,实现支付宝等
密码输入的效果,使用者可自定义密码是否可见。代码已托管到github,有需要的话可以
去我的github下载。
话不多说,先看效果:图左为隐藏密码的显示效果,图右为不隐藏密码的显示效果,该可见性可由自定义密码输入框控件的isHide属性来确定
isHide="true" 表示隐藏输入的密码,isHide="false" 表示输入的密码可见。
下面就来介绍一下整个效果实现的过程:
一. 拆分控件
整个视图可分为三个子控件:
1.标题栏
包含一个返回按钮,和一个标题文本,就是一个简单的Button和TextView。我们可以自定义其标题和功能。不用过多介绍。
2.自定义密码显示框
该显示框用于显示用户输入的密码,并根据用户的设置,以明文或暗文的方式演示输入的密码。为了较好的显示其输入
这里继承该控件了EditText,并为其添加了一些属性。在自定义密码显示框初始化时获取相关属性,并在onDraw方法中绘制整个
密码输入框。其中包括绘制背景、绘制分割线、绘制密码。同时,在设置密码位数的属性后,也为其添加了密码位数输入已满的
监听事件,给使用者及时提供输入反馈。
3.自定义输入键盘
支付宝密码输入时,不是调用系统的软键盘进行输入,而是通过自定义的密码键盘进行密码输入。因此在实现此效果时
就必须自定义一个密码键盘。自定义输入键盘主要包含10个数字按键和一个确定按键和删除按键。同时,也为其子控件添加了事
件监听,从而获取使用者的输入。
二.实现过程
主要介绍一下密码显示框的输入键盘的实现。
1.自定义密码显示框View
先说说自定义View的几种方式:(1)继承View重写onDraw方法,主要实现一些不规则的效果;(2)继承ViewGroup
派生新的Layout,主要实现自定义的布局;(3)继承特定的View(如EditView),一般用于扩展某种已有的View的功能;(4)
继承特定的ViewGroup,一般用于几种View组合在 一起而实现的效果。
在此控件中采用的是自定义一个类并继承自EditText,并在values文件夹下新建一个pwdwidget.xml来声明自定义View的一些属性。
- <resources>
- <declare-styleable name="CustomPwdWidgt">
- <!-- 密码的个数 -->
- <attr name="passwordNumber" format="integer"/>
- <!-- 密码圆点的半径 -->
- <attr name="passwordRadius" format="dimension" />
- <!-- 分割线的大小 -->
- <attr name="divisionLineSize" format="dimension" />
- <!-- 是否隐藏输入的数字-->
- <attr name="isHide" format="boolean"/>
- .
- .
- .
- </declare-styleable>
- </resources>
在自定义密码显示框View初始化构造方法中获取设置的属性值,并在重写onDraw方法,绘制我们所需要的密码框效
果:
- public CustomPwdWidget(Context context, AttributeSet attrs) {
- super(context, attrs);
- initPaint();
- initAttributeSet(context, attrs); //获取属性
- // 设置输入模式是密码
- //setInputType(EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
- setInputType(EditorInfo.TYPE_CLASS_NUMBER);
- // 不显示光标
- setCursorVisible(false);
- }
重点介绍一下绘制密码的方法,通过获取键盘输入的字符的长度,来确定绘制几个字符,并确定每个字符所在的位
- @Override
- protected void onDraw(Canvas canvas) {
- int passwordWidth = getWidth() - (mPasswordNumber - 1) * mDivisionLineSize - mBgSize * 2;
- mPasswordItemWidth = passwordWidth / mPasswordNumber; //每个密码框的宽度
- // 绘制背景
- drawBg(canvas);
- // 绘制分割线
- drawDivisionLine(canvas);
- // 绘制密码
- drawPassword(canvas);
- }
置。同时,在绘制密码时,我们需要判断在使用自定义密码输入控件时设置的isHide属性,若isHide为true,则绘制圆圈表明密码
不可见;若isHide'属性为false,则绘制输入的字符表明密码可见。三个绘制方法如下:
- /**
- * 绘制背景
- */
- private void drawBg(Canvas canvas) {
- mPaint.setColor(mBgColor);
- // 设置画笔为空心
- mPaint.setStyle(Paint.Style.STROKE);
- mPaint.setStrokeWidth(mBgSize);
- RectF rectF = new RectF(mBgSize/2, mBgSize/2, getWidth() - mBgSize/2, getHeight() - mBgSize/2);
- // 如果没有设置圆角,就画矩形
- if (mBgCorner == 0) {
- canvas.drawRect(rectF, mPaint);
- } else {
- // 如果有设置圆角就画圆矩形
- canvas.drawRoundRect(rectF, mBgCorner, mBgCorner, mPaint);
- }
- }
- /**
- * 绘制密码
- */
- private void drawPassword(Canvas canvas) {
- int passwordLength = getText().length();
- mPaint.setColor(mPasswordColor);
- // 设置画笔为实心
- mPaint.setStyle(Paint.Style.FILL);
- String password = getText().toString();
- for (int i = 0; i < passwordLength; i++) {
- int cx = i * mDivisionLineSize + i * mPasswordItemWidth + mPasswordItemWidth / 2 + mBgSize;
- //判断是否隐藏的属性,来绘制密码
- if(mIsHide){
- //隐藏密码,用圆圈代替
- canvas.drawCircle(cx, getHeight() / 2, mPasswordRadius, mPaint);
- }else{
- //不隐藏密码,并让数字居中显示
- mPaint.setTextSize(getHeight()/2);
- canvas.drawText(password.charAt(i)+"",cx, getHeight()/4 *3, mPaint);
- }
- }
- }
- /**
- * 绘制分割线
- */
- private void drawDivisionLine(Canvas canvas) {
- mPaint.setStrokeWidth(mDivisionLineSize);
- mPaint.setColor(mDivisionLineColor);
- for (int i = 0; i < mPasswordNumber - 1; i++) {
- //int startX = (i + 1) * mDivisionLineSize + (i + 1) * mPasswordItemWidth + mBgSize;
- int startX = (i)*mDivisionLineSize+(i+1)*mPasswordItemWidth+mBgSize+mDivisionLineSize/2;
- canvas.drawLine(startX, mBgSize, startX, getHeight() - mBgSize, mPaint);
- }
- }
同时,给自定义密码显示框设置了回调监听事件,在添加密码时若检测到密码输入已满时,会触发该监听事件。此方
法需要通过使用者自己实现,以达到不同的监听效果。
- public void addPassword(String number) {
- number = getText().toString().trim() + number;
- setText(number);
- //当输入的字符数等于或超过设置的字符输入个数时,会回调设置的监听方法
- if (number.length() >= mPasswordNumber) {
- mListener.passwordFullListener(number);
- return;
- }
- }
2.自定义键盘View
自定义键盘相对就比较简单,就包含了一些TextView的数组按键和ImageView的确定及删除按键。通过给View设置监听
事件,并给View中的字元素循环设置监听事件,确保每个子元素在点击时都能响应onClick事件。在onClick响应事件中,通
过判断点击的子元素是TextView还是ImageView来判断点击的是数组按键还是确定或删除按键,逻辑如下:
- /**
- * 只要点击了自定义的键盘,就会响应该事件,并判断点击的是点击了什么
- * @param v
- */
- @Override
- public void onClick(View v) {
- View clickView = v;
- if (clickView instanceof TextView) {
- // 如果点击的是TextView
- String number = ((TextView) clickView).getText().toString();
- if (!TextUtils.isEmpty(number)) {
- if (mListener != null) {
- // 回调
- mListener.click(number);
- }
- }
- } else if (clickView instanceof ImageView) {
- //如果点击的使ImageView,就判断是确认还是删除
- switch (clickView.getId()){
- case R.id.confirm:
- //回调监听的confirm方法
- mListener.confirm();
- break;
- case R.id.cancel:
- //回调监听的cancel方法
- mListener.cancel();
- break;
- }
- }
- }
为了让使用者能够自定义确定按钮和删除按钮的实习方法,我们为自定义键盘添加了事件监听接口,使用者在设置两个
监听事件后会回调其中的方法,此时在该方法中就可以实现自己实现的逻辑。demo里面只是简单的将输入的内容用Toast打
印出来。回调监听接口如下:
- /**
- * 设置键盘的点击回调监听
- */
- public void setOnCustomerKeyboardClickListener(CustomerKeyboardClickListener listener) {
- this.mListener = listener;
- }
- /**
- * 点击键盘的回调监听
- */
- public interface CustomerKeyboardClickListener {
- public void click(String number);
- public void confirm();
- public void cancel();
- }
3.使用过程(也就是最想看到的一步)
主要步骤就是实现事件监听接口,并为自定义控件添加监听事件,同时实现其回调的方法。
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- pwdEdit = (CustomPwdWidget) findViewById(R.id.pwdEdit);
- keboard = (CustomKeyboard) findViewById(R.id.keyboard);
- pwdEdit.setPasswordFullListener(this);
- keboard.setOnCustomerKeyboardClickListener(this);
- }
- /**
- * 密码输入已满回调的监听事件
- * @param number
- */
- @Override
- public void passwordFullListener(String number) {
- mNumber = number;
- }
- /**
- * 键盘的点击数字键的响应事件
- * @param number
- */
- @Override
- public void click(String number) {
- pwdEdit.addPassword(number);
- }
- /**
- * 点击确认键的回调事件
- */
- @Override
- public void confirm() {
- if(!TextUtils.isEmpty(mNumber)){
- mNumber = mNumber.substring(0,4); //4为设置输入数字长度,截取输入的长度
- Toast.makeText(getApplicationContext(),mNumber,Toast.LENGTH_SHORT).show();
- }
- }
- /**
- * 点击删除按键的回调事件
- */
- @Override
- public void cancel() {
- mNumber = null;
- pwdEdit.deleteLastPassword();
- }
三.总结
本次demo的效果参看了http://blog.csdn.net/z240336124/article/details/53739790其中实现的方法,并进行了优化及
方法的扩展。以上代码为demo中的部分源码,若要获取源码可去我的github中下载,地址:https://github.com/851151582/CustomPwdWidget。
欢迎修改及指正代码中的错误。若有什么问题,可以邮件我2366771414@qq.com,谢谢!
- Android自定义密码输入框——(仿支付宝等)
- Android自定义控件开发系列(三)——仿支付宝六位支付密码输入页面
- android 仿支付宝密码输入框
- Android自定义控件开发系列——仿支付宝六位支付密码输入
- Android仿支付宝支付密码输入框
- Android仿支付宝支付密码输入框
- Android 仿支付宝支付密码输入框
- android中6个EditText输入验证码(仿支付宝支付输入密码框)
- 自定义view仿支付宝密码输入框
- 仿支付宝支付密码输入框
- Android仿支付宝淘宝 - 自定义密码输入框和键盘
- Android开发笔记(一百四十六)仿支付宝的支付密码输入框
- Android 仿支付宝密码框的EditText输入框
- [Android]仿支付宝自定义View密码框
- Andriod 仿支付宝密码输入框
- 【笔记】仿支付宝密码输入框
- 仿支付宝密码输入框
- 自定义View之仿支付宝输入六位密码
- 如何交叉取一个表的数据
- 语法基础——PHP语法基础
- C++/MFC-GDI绘图之CRgn区域,CFile
- 动态网页开发基础
- CentOS7.0安装JDK1.8
- Android自定义密码输入框——(仿支付宝等)
- 如何进行线结构光与单目相机的联合标定
- 详解设计模式六大原则
- svg转图片下载
- Git:release分支有了不想要的topic分支的代码
- Maven中dependencies与dependencyManagement的区别
- Openwrt WIFI探针开发【三】
- XP MODE磁盘的极限压缩方法(.VHD文件的压缩)
- 自定义域名访问Azure Storage Blob中的内容