AndroID 自定义输入支付密码的软键盘
有项目需求需要做一个密码锁功能,还有自己的软键盘,类似与支付宝那种,这里是整理的资料,大家可以看下,如有错误,欢迎留言指正
需求:要实现类似支付宝的输入支付密码的功能,效果图如下:
软键盘效果图
使用 androID.inputmethodservice.KeyboardVIEw 这个类自定义软键盘
软键盘的实现
1. 自定义只输入数字的软键盘 PasswordKeyboardVIEw 类,继承自 androID.inputmethodservice.KeyboardVIEw
/** * 输入数字密码的键盘布局控件。 */public class PasswordKeyboardVIEw extends KeyboardVIEw implements androID.inputmethodservice.KeyboardVIEw.OnKeyboardActionListener { // 用于区分左下角空白的按键 private static final int KEYCODE_EMPTY = -10; private int mDeleteBackgroundcolor; private Rect mDeleteDrawRect; private Drawable mDeleteDrawable; private IOnKeyboardListener mOnKeyboardListener; public PasswordKeyboardVIEw(Context context,AttributeSet attrs) { super(context,attrs); init(context,attrs,0); } public PasswordKeyboardVIEw(Context context,AttributeSet attrs,int defStyleAttr) { super(context,defStyleAttr); init(context,defStyleAttr); } private voID init(Context context,int defStyleAttr) { TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.PasswordKeyboardVIEw,defStyleAttr,0); mDeleteDrawable = a.getDrawable( R.styleable.PasswordKeyboardVIEw_pkvDeleteDrawable); mDeleteBackgroundcolor = a.getcolor( R.styleable.PasswordKeyboardVIEw_pkvDeleteBackgroundcolor,color.transparent); a.recycle(); // 设置软键盘按键的布局 Keyboard keyboard = new Keyboard(context,R.xml.keyboard_number_password); setKeyboard(keyboard); setEnabled(true); setPrevIEwEnabled(false); setonKeyboardActionListener(this); } @OverrIDe public voID onDraw(Canvas canvas) { super.onDraw(canvas); // 遍历所有的按键 List<Keyboard.Key> keys = getKeyboard().getKeys(); for (Keyboard.Key key : keys) { // 如果是左下角空白的按键,重画按键的背景 if (key.codes[0] == KEYCODE_EMPTY) { drawKeyBackground(key,canvas,mDeleteBackgroundcolor); } // 如果是右下角的删除按键,重画背景,并且绘制删除的图标 else if (key.codes[0] == Keyboard.KEYCODE_DELETE) { drawKeyBackground(key,mDeleteBackgroundcolor); drawDeletebutton(key,canvas); } } } // 绘制按键的背景 private voID drawKeyBackground(Keyboard.Key key,Canvas canvas,int color) { colorDrawable drawable = new colorDrawable(color); drawable.setBounds(key.x,key.y,key.x + key.wIDth,key.y + key.height); drawable.draw(canvas); } // 绘制删除按键 private voID drawDeletebutton(Keyboard.Key key,Canvas canvas) { if (mDeleteDrawable == null) return; // 计算删除图标绘制的坐标 if (mDeleteDrawRect == null || mDeleteDrawRect.isEmpty()) { int intrinsicWIDth = mDeleteDrawable.getIntrinsicWIDth(); int intrinsicHeight = mDeleteDrawable.getIntrinsicHeight(); int drawWIDth = intrinsicWIDth; int drawHeight = intrinsicHeight; // 限制图标的大小,防止图标超出按键 if (drawWIDth > key.wIDth) { drawWIDth = key.wIDth; drawHeight = drawWIDth * intrinsicHeight / intrinsicWIDth; } if (drawHeight > key.height) { drawHeight = key.height; drawWIDth = drawHeight * intrinsicWIDth / intrinsicHeight; } // 获取删除图标绘制的坐标 int left = key.x + (key.wIDth - drawWIDth) / 2; int top = key.y + (key.height - drawHeight) / 2; mDeleteDrawRect = new Rect(left,top,left + drawWIDth,top + drawHeight); } // 绘制删除的图标 if (mDeleteDrawRect != null && !mDeleteDrawRect.isEmpty()) { mDeleteDrawable.setBounds(mDeleteDrawRect.left,mDeleteDrawRect.top,mDeleteDrawRect.right,mDeleteDrawRect.bottom); mDeleteDrawable.draw(canvas); } } @OverrIDe public voID onKey(int primaryCode,int[] keyCodes) { // 处理按键的点击事件 // 点击删除按键 if (primaryCode == Keyboard.KEYCODE_DELETE) { if (mOnKeyboardListener != null) { mOnKeyboardListener.onDeleteKeyEvent(); } } // 点击了非左下角按键的其他按键 else if (primaryCode != KEYCODE_EMPTY) { if (mOnKeyboardListener != null) { mOnKeyboardListener.onInsertKeyEvent( Character.toString((char) primaryCode)); } } } @OverrIDe public voID onPress(int primaryCode) { } @OverrIDe public voID onRelease(int primaryCode) { } @OverrIDe public voID onText(CharSequence text) { } @OverrIDe public voID swipeleft() { } @OverrIDe public voID swipeRight() { } @OverrIDe public voID swipeDown() { } @OverrIDe public voID swipeUp() { } /** * 设置键盘的监听事件。 * * @param Listener * 监听事件 */ public voID setIOnKeyboardListener(IOnKeyboardListener Listener) { this.mOnKeyboardListener = Listener; } public interface IOnKeyboardListener { voID onInsertKeyEvent(String text); voID onDeleteKeyEvent(); }}
2. 自定义属性:
values/attrs.xml
<declare-styleable name="PasswordKeyboardVIEw"> <attr name="pkvDeleteDrawable" format="reference"/> <attr name="pkvDeleteBackgroundcolor" format="color|reference"/></declare-styleable>
3. 软键盘按键的布局文件 res/xml/keyboard_number_password:
说明:
androID:keyWIDth="33.33333%p":指定按键的宽度,保证键盘的每一列宽度一致 androID:keyHeight="8%p":设置键盘的高度 androID:horizontalGap="1dp":实现键盘每一列之间的分割线 androID:verticalGap="1dp":实现键盘每一行之间的分割线<?xml version="1.0" enCoding="utf-8"?><Keyboard xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:keyWIDth="33.33333%p" androID:keyHeight="8%p" androID:horizontalGap="1dp" androID:verticalGap="1dp"> <Row> <Key androID:codes="49" androID:keyLabel="1"/> <Key androID:codes="50" androID:keyLabel="2"/> <Key androID:codes="51" androID:keyLabel="3"/> </Row> <Row> <Key androID:codes="52" androID:keyLabel="4"/> <Key androID:codes="53" androID:keyLabel="5"/> <Key androID:codes="54" androID:keyLabel="6"/> </Row> <Row> <Key androID:codes="55" androID:keyLabel="7"/> <Key androID:codes="56" androID:keyLabel="8"/> <Key androID:codes="57" androID:keyLabel="9"/> </Row> <Row> <Key androID:codes="-10" androID:keyLabel=""/> <Key androID:codes="48" androID:keyLabel="0"/> <Key androID:codes="-5" androID:keyIcon="@mipmap/keyboard_backspace"/> </Row></Keyboard>
3. 在布局中引用软键盘控件:
<[包名].PasswordKeyboardVIEw androID:layout_wIDth="match_parent" androID:layout_height="wrap_content" androID:background="#b0b0b0" androID:focusable="true" androID:focusableIntouchMode="true" androID:keyBackground="#ffffff" androID:keyTextcolor="#000000" androID:shadowcolor="#00000000" androID:shadowRadius="0" app:pkvDeleteBackgroundcolor="#d2d2d2" app:pkvDeleteDrawable="@drawable/keyboard_backspace" />
随机数字键盘的实现
目前能想到的有两种实现方式:
1. 在 onDraw 方法里重新绘制键盘上的文字,覆盖掉原来的键盘,这种实现方式相对比较麻烦。
2. 调用 KeyboardVIEw.setKeyboard() 方法重新设置键盘,实现的代码如下:
// 0-9 的数字private final List<Character> keyCodes = Arrays.asList( '0','1','2','3','4','5','6','7','8','9');/** * 随机打乱数字键盘上显示的数字顺序。 */public voID shuffleKeyboard() { Keyboard keyboard = getKeyboard(); if (keyboard != null && keyboard.getKeys() != null && keyboard.getKeys().size() > 0) { // 随机排序数字 Collections.shuffle(keyCodes); // 遍历所有的按键 List<Keyboard.Key> keys = getKeyboard().getKeys(); int index = 0; for (Keyboard.Key key : keys) { // 如果按键是数字 if (key.codes[0] != KEYCODE_EMPTY && key.codes[0] != Keyboard.KEYCODE_DELETE) { char code = keyCodes.get(index++); key.codes[0] = code; key.label = Character.toString(code); } } // 更新键盘 setKeyboard(keyboard); }}
调用 shuffleKeyboard 即可生成随机的键盘。
最终实现的效果如下:
随机键盘
踩坑
1. 点击按键的放大镜效果提示
软键盘默认点击按键时会显示放大镜效果的提示,如果不需要可以使用 setPrevIEwEnabled(false) 设置不显示提示。
可以在布局中使用 androID:keyPrevIEwLayout 指定提示文字的布局。
2. 按键文字不清晰
软键盘按键默认带有阴影效果,会导致文字不清楚,可以使用下面方式去掉阴影:
<[包名].PasswordKeyboardVIEw androID:shadowcolor="@color/transparent" androID:shadowRadius="0" ... />
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
总结以上是内存溢出为你收集整理的Android 自定义输入支付密码的软键盘实例代码全部内容,希望文章能够帮你解决Android 自定义输入支付密码的软键盘实例代码所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)