Android自定义键盘的实现(数字键盘和字母键盘)
在项目中,产品对于输入方式会有特殊的要求,需要对输入方式增加特定的限制,这就需要采用自定义键盘。本文主要讲述数字键盘和字母键盘的自定义实现。
项目地址:
键盘效果:
自定义键盘的实现步骤如下:
- 自定义customkeyboard, 继承自系统keyboard,实现keyboardview.onkeyboardactionlistener相关接口,以处理用户的点击回调;
- 自定义customkeyboardview, 继承自keyboardview,实现自定义键盘绘制;
- 创建keyboardmanager, 用于处理自定义键盘的显示以及和输入ui的交互
自定义customkeyboard
android系统keyboard的构造方法如下:
/** * creates a keyboard from the given xml key layout file. * @param context the application or service context * @param xmllayoutresid the resource file that contains the keyboard layout and keys. */ public keyboard(context context, int xmllayoutresid) { this(context, xmllayoutresid, 0); } /** * creates a keyboard from the given xml key layout file. weeds out rows * that have a keyboard mode defined but don't match the specified mode. * @param context the application or service context * @param xmllayoutresid the resource file that contains the keyboard layout and keys. * @param modeid keyboard mode identifier * @param width sets width of keyboard * @param height sets height of keyboard */ public keyboard(context context, @xmlres int xmllayoutresid, int modeid, int width, int height) { ... }
其中,参数xmllayoutresid是必须的,另外还可以通过计算系统键盘的高度来设定自定义键盘的高度。
xmllayoutres的格式如下:
<?xml version="1.0" encoding="utf-8"?> <keyboard android:keywidth="24.9%p" android:keyheight="49dp" android:horizontalgap="0.1333%p" android:verticalgap="1px" xmlns:android="http://schemas.android.com/apk/res/android"> <row> <key android:codes="49" android:keyedgeflags="left" android:keylabel="1" /> <key android:codes="50" android:keylabel="2" /> <key android:codes="51" android:keylabel="3" /> <key android:codes="-5" android:iconpreview="@drawable/key_num_del_bg" android:isrepeatable="true"/> </row> ... </keyboard>
详细的数字键盘和字母键盘xmllayoutres资源文件可以从以下链接获取:
数字键盘xmllayoutres
字母键盘xmllayoutres
customkeyboard主要目的就是赋予xmllayoutres并实现特定按键的点击处理,其主要重载的方法是onkey(int primarycode, int[] keycodes)。详细代码如下:
public abstract class basekeyboard extends keyboard implements keyboardview.onkeyboardactionlistener{ @override public void onkey(int primarycode, int[] keycodes) { if(null != medittext && medittext.hasfocus() && !handlespecialkey(primarycode)) { editable editable = medittext.gettext(); int start = medittext.getselectionstart(); int end = medittext.getselectionend(); if (end > start){ editable.delete(start,end); } if(primarycode == keycode_delete) { if(!textutils.isempty(editable)) { if(start > 0) { editable.delete(start-1,start); } } }else if(primarycode == getkeycode(r.integer.hide_keyboard)){ hidekeyboard(); }else { editable.insert(start,character.tostring((char) primarycode)); } } } public abstract boolean handlespecialkey(int primarycode); }
如上所示是basekeyboard,数字键盘和字母键盘需要继承它,并实现public abstract boolean handlespecialkey(int primarycode)方法。
自定义customkeyboardview
keyboardview 是承载不同的keyboard并绘制keyboard, 是键盘布局的绘制板, 并与系统交互。通过继承keyboardview自定义customkeyboardview,可以对按键样式实现自定义。考察keyboardview的源码,发现其ui样式都是private类型,这就需要通过反射的方式获取特定的ui属性,并重新进行赋值,同时重载ondraw()方法,在ondraw()中重新绘制。
详细代码可以参考github源码: basekeyboardview源码
自定义键盘的ui效果如下:
数字键盘
字母键盘
创建keyboardmanager
主要处理以下功能逻辑:
- 绑定edittext和keyboard,监听edittext的onfocuschangelistener,处理键盘弹出和键盘掩藏;
- 处理系统键盘和自定义键盘之间的切换关系;
- 处理键盘区域其他自定义view的显示,比如需要让键盘自动搜索功能时,可在manager中进行相关处理
以绑定edittext为例:
public void bindtoeditor(edittext edittext, basekeyboard keyboard) { hidesystemsoftkeyboard(edittext); edittext.settag(r.id.bind_keyboard_2_editor, keyboard); if (keyboard.getkeystyle() == null) { keyboard.setkeystyle(mdefaultkeystyle); } edittext.setonfocuschangelistener(editorfocuschangelistener); } private final view.onfocuschangelistener editorfocuschangelistener = new view.onfocuschangelistener() { @override public void onfocuschange(final view v, boolean hasfocus) { if (v instanceof edittext) { if (hasfocus) { v.postdelayed(new runnable() { @override public void run() { showsoftkeyboard((edittext) v); } },300); } else { hidesoftkeyboard(); } } } }; public void showsoftkeyboard(edittext edittext) { mrootview.addonlayoutchangelistener(monlayoutchangelistener); basekeyboard keyboard = getbindkeyboard(edittext); if (keyboard == null) { log.e(tag, "edit text not bind to keyboard"); return; } keyboard.setedittext(edittext); keyboard.setnextfocusview(mkeyboardwithsearchview.getedittext()); initkeyboard(keyboard); ... }
键盘的使用方式非常简单, 通过keyboardmanager实现调用
数字键盘:
keyboardmanager keyboardmanagernumber = new keyboardmanager(this); keyboardmanagernumber.bindtoeditor(edittext2, new numberkeyboard(context,numberkeyboard.default_number_xml_layout));
字母键盘:
keyboardmanager keyboardmanagerabc = new keyboardmanager(this); keyboardmanagerabc.bindtoeditor(edittext1, new abckeyboard(context, abckeyboard.default_abc_xml_layout));
至此,自定义键盘的实现就介绍完了,文中介绍的更多还是实现的思路,具体实现可以参考github,有需要的用户也可以直接修改项目的源码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 阿里助手将老店铺的产品迁移到新店铺的方法