原标题:Android 自定义控件 - 仿支付宝数字键盘
简介
在一些带有支付功能的 App 中,输入的密码一般只能是纯数字,虽然我们可以指定 EditText 输入框只能输入数字,但是为了提供用户的使用体验,我们往往更倾向于使用自定义的纯数字键盘。
本文效果:
实现步骤:
集成系统的 KeyBoardView 类,在初始化时初始化键盘布局,设置 KeyBoard 对象。
实现 OnKeyboardActionListener 接口,处理按键交互事件。
根据需求绘制按键背景和按键图标。
设置监听器,将输入的内容回调给调用方。
键盘布局
在 res/xml/ 目录下创建 xml 文件:key_password_number.xml
android:horizontalGap="1dp"
android:keyHeight="9%p"
android:keyWidth="33.3333%p"
android:verticalGap="1dp">
android:codes="49"
android:keyLabel="1"/>
android:codes="50"
android:keyLabel="2"/>
android:codes="51"
android:keyLabel="3"/>
android:codes="52"
android:keyLabel="4"/>
android:codes="53"
android:keyLabel="5"/>
android:codes="54"
android:keyLabel="6"/>
android:codes="55"
android:keyLabel="7"/>
android:codes="56"
android:keyLabel="8"/>
android:codes="57"
android:keyLabel="9"/>
android:codes="-10"
android:keyLabel=""/>
android:codes="48"
android:keyLabel="0"/>
android:codes="-5"
android:keyLabel=""/>
继承 KeyBoardView
publicclassPwdKeyboardViewextendsKeyboardViewimplementsKeyboardView.OnKeyboardActionListener{
privatestaticfinalString TAG = "PwdKeyboardView";
privatestaticfinalintKEY_EMPTY = - 10;
privateintdelKeyBackgroundColor = 0xffcccccc;
privateRect keyIconRect;
publicPwdKeyboardView(Context context, AttributeSet attrs){
super(context, attrs);
Log.d(TAG, "PwdKeyboardView: two params");
init(context);
}
publicPwdKeyboardView(Context context, AttributeSet attrs, intdefStyleAttr){
super(context, attrs, defStyleAttr);
Log.d(TAG, "PwdKeyboardView: three params");
init(context);
}
privatevoidinit(Context context){
Keyboard keyboard = newKeyboard(context, R.xml.key_password_number); // 初始化 keyboard
setKeyboard(keyboard);
setEnabled( true);
setFocusable( true);
setPreviewEnabled( false); // 设置点击按键不显示预览气泡
setOnKeyboardActionListener( this);
}
/**
* 重新绘制删除按键和空白键
*
* @paramcanvas
*/
@Override
publicvoidonDraw(Canvas canvas){
super.onDraw(canvas);
List keys = getKeyboard().getKeys();
for(Keyboard.Key key : keys) {
if(key.codes[ 0] == KEY_EMPTY) {
// 绘制空白键背景
drawKeyBackground(key, canvas, delKeyBackgroundColor);
}
if(key.codes[ 0] == Keyboard.KEYCODE_DELETE) {
// 删除删除按键背景
drawKeyBackground(key, canvas, delKeyBackgroundColor);
// 绘制删除按键图标
drawKeyIcon(key, canvas, getResources().getDrawable(R.drawable.ic_delete));
}
}
}
/**
* 绘制按键的背景
*
* @paramkey
* @paramcanvas
* @paramcolor
*/
privatevoiddrawKeyBackground(Keyboard.Key key, Canvas canvas, intcolor){
ColorDrawable drawable = newColorDrawable(color);
drawable.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
drawable.draw(canvas);
}
/**
* 绘制按键的 icon
*
* @paramkey
* @paramcanvas
* @paramiconDrawable
*/
privatevoiddrawKeyIcon(Keyboard.Key key, Canvas canvas, Drawable iconDrawable){
if(iconDrawable == null) {
return;
}
// 计算按键icon 的rect 范围
if(keyIconRect == null|| keyIconRect.isEmpty()) {
// 得到 keyicon 的显示大小,因为图片放在不同的drawable-dpi目录下,显示大小也不一样
intintrinsicWidth = iconDrawable.getIntrinsicWidth();
intintrinsicHeight = iconDrawable.getIntrinsicHeight();
intdrawWidth = intrinsicWidth;
intdrawHeight = intrinsicHeight;
// 限制图片的大小,防止图片按键范围
if(drawWidth > key.width) {
drawWidth = key.width;
// 此时高就按照比例缩放
drawHeight = ( int) (drawWidth * 1.0f/ intrinsicWidth * intrinsicHeight);
} elseif(drawHeight > key.height) {
drawHeight = key.height;
drawWidth = ( int) (drawHeight * 1.0f/ intrinsicHeight * intrinsicWidth);
}
// 获取图片的 x,y 坐标,图片在按键的正中间
intleft = key.x + key.width / 2- drawWidth / 2;
inttop = key.y + key.height / 2- drawHeight / 2;
keyIconRect = newRect(left, top, left + drawWidth, top + drawHeight);
}
if(keyIconRect != null&& !keyIconRect.isEmpty()) {
iconDrawable.setBounds(keyIconRect);
iconDrawable.draw(canvas);
}
}
@Override
publicvoidonPress(intprimaryCode){
}
@Override
publicvoidonRelease(intprimaryCode){
}
/**
* 处理按键的点击事件
*/
@Override
publicvoidonKey(intprimaryCode, int[] keyCodes){
Log.d(TAG, "onKey: primaryCode = "+ primaryCode + ", keyCodes = "+ Arrays.toString(keyCodes));
if(primaryCode == KEY_EMPTY) {
return;
}
if(listener != null) {
if(primaryCode == Keyboard.KEYCODE_DELETE) {
listener.onDelete();
} else{
listener.onInput(String.valueOf(( char) primaryCode));
}
}
}
@Override
publicvoidonText(CharSequence charSequence){
}
@Override
publicvoidswipeLeft(){
}
@Override
publicvoidswipeRight(){
}
@Override
publicvoidswipeDown(){
}
@Override
publicvoidswipeUp(){
}
publicinterfaceOnKeyListener{
// 输入回调
voidonInput(String text);
// 删除回调
voidonDelete();
}
privateOnKeyListener listener;
publicvoidsetOnKeyListener(OnKeyListener listener){
this.listener = listener;
}
}
使用 PwdKeyboardView
android:id= "@+id/key_board"
android:layout_width= "match_parent"
android:layout_height= "wrap_content"
android:background= "#919191"
android:keepScreenOn= "true"
android:keyBackground= "@drawable/selector_key_board"
android:keyTextColor= "@android:color/black"
android:keyTextSize= "26sp"
android:shadowRadius= "0"/>
显示结果为:
完整代码:https://github.com/xing16/PwdKeyboardView返回搜狐,查看更多
责任编辑: