手机上输入文字,都是通过系统自带的软键盘,这个软键盘可以是Android自带的,也可以是第三方软键盘如搜狗输入法。多数情况下面,系统自带的软键盘已经够用了,可是总有少数情况,系统软键盘无法满足开发者的要求,比如以下几个需求,系统软键盘就无法处理:
1、像手机号码与支付密码,只需要输入数字,连标点符号都不需要。然而系统软键盘即使切换到123数字模式,依旧显示包括标点符号在内的冗余按键。
2、系统软键盘固定在屏幕下方弹出,无法做为控件嵌入到页面布局中,更无法指定软键盘的显示位置。
3、系统软键盘会自动响应EditText的焦点变更事件,常常在意料之外突然之间蹦出来,弄得开发者要么剥夺EditText的焦点,要么强行关闭软键盘显示,但无论哪种方式都得开发者强行**,很不方便。
基于以上情况,要想满足这些定制需求,只能对输入法自定义软键盘了。全数字的软键盘界面倒也简单,下面先来个数字键盘的效果图。
这个键盘只有0-9十个数字,再加一个退格键,可谓十个兄弟家徒四壁,真是再直白不过了。那么这个软键盘又是如何实现的呢?其实它跟平常的自定义控件基本类似,只在细节上有所差异,下面分步说明自定义软键盘的过程。
1、我们知道,自定义控件要么重写onDraw方法来绘制控件界面,要么从layout布局文件中加载控件界面。软键盘采取的是后一种方式,只不过它的布局文件不是放在res/layout目录,而是保存在res/xml目录。
2、自定义控件的主要工作是书写自定义的控件类,自定义软键盘也不例外,有了自定义的控件类,才能处理十个数字键的按键动作,才能把软键盘做为普通的控件嵌入到其它布局文件中。
3、软键盘不是一个孤立的控件,它的按键动作需要实时在某个编辑框中把数字显示出来,所以在使用时还得给它绑定一个EditText,这样软键盘才知道我的按键要输出给这个EditText,而不是输出给那个EditText。
俗话说,百闻不如一见,所以在说明具体的实现步骤之前,还是先看看最终的软键盘使用动图,带上这个感性认识去学习会更有帮助。
接下来阐述自定义软键盘的三个步骤,首先要定义软键盘的布局文件,在res/xml目录创建名为inputkeyboard.xml的文件,内部的根节点为Keyboard,其下挂了四个Row节点表示有四行,每个Row节点下又挂了三个Key节点,表示每行有三个按键。完整的键盘布局文件如下所示:
然后是编写自定义软键盘的控件代码了,这里的关键是用自定义的键盘布局替换掉系统默认的键盘布局,自定义代码如下所示:
最后要给软键盘绑定对应的EditText对象,即当软键盘发生按键动作时,要把按键结果显示在哪个EditText上。这个操作就是调用KeyboardView的setOnKeyboardActionListener方法,设置一个键盘事件监听器,监听器内部主要实现了onKey方法,每当发现合法的按键事件(0-9与退格键),则同步修改EditText对象的文本。这部分代码补充到前面的自定义控件类KeyboardLayout之中:
至此我们可以像使用其它控件一样直接把软键盘加入到页面布局啦,注意指定键盘布局的自定义属性:
点此查看Android开发笔记的完整目录
__________________________________________________________________________
本文现已同步发布到微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。
1、像手机号码与支付密码,只需要输入数字,连标点符号都不需要。然而系统软键盘即使切换到123数字模式,依旧显示包括标点符号在内的冗余按键。
2、系统软键盘固定在屏幕下方弹出,无法做为控件嵌入到页面布局中,更无法指定软键盘的显示位置。
3、系统软键盘会自动响应EditText的焦点变更事件,常常在意料之外突然之间蹦出来,弄得开发者要么剥夺EditText的焦点,要么强行关闭软键盘显示,但无论哪种方式都得开发者强行**,很不方便。
基于以上情况,要想满足这些定制需求,只能对输入法自定义软键盘了。全数字的软键盘界面倒也简单,下面先来个数字键盘的效果图。
这个键盘只有0-9十个数字,再加一个退格键,可谓十个兄弟家徒四壁,真是再直白不过了。那么这个软键盘又是如何实现的呢?其实它跟平常的自定义控件基本类似,只在细节上有所差异,下面分步说明自定义软键盘的过程。
1、我们知道,自定义控件要么重写onDraw方法来绘制控件界面,要么从layout布局文件中加载控件界面。软键盘采取的是后一种方式,只不过它的布局文件不是放在res/layout目录,而是保存在res/xml目录。
2、自定义控件的主要工作是书写自定义的控件类,自定义软键盘也不例外,有了自定义的控件类,才能处理十个数字键的按键动作,才能把软键盘做为普通的控件嵌入到其它布局文件中。
3、软键盘不是一个孤立的控件,它的按键动作需要实时在某个编辑框中把数字显示出来,所以在使用时还得给它绑定一个EditText,这样软键盘才知道我的按键要输出给这个EditText,而不是输出给那个EditText。
俗话说,百闻不如一见,所以在说明具体的实现步骤之前,还是先看看最终的软键盘使用动图,带上这个感性认识去学习会更有帮助。
接下来阐述自定义软键盘的三个步骤,首先要定义软键盘的布局文件,在res/xml目录创建名为inputkeyboard.xml的文件,内部的根节点为Keyboard,其下挂了四个Row节点表示有四行,每个Row节点下又挂了三个Key节点,表示每行有三个按键。完整的键盘布局文件如下所示:
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="34%p" android:horizontalGap="1px" android:verticalGap="1px" android:keyHeight="55dp"> <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="-3" android:keyEdgeFlags="left" android:keyIcon="@drawable/sym_keyboard_done" /> <Key android:codes="48" android:keyLabel="0" /> <Key android:codes="-5" android:isRepeatable="true" android:keyEdgeFlags="right" android:keyIcon="@drawable/sym_keyboard_delete" /> </Row> </Keyboard>上面这个xml键盘布局,到时候将作为自定义属性传给软键盘控件,所以要在res/values/attrs.xml中补充下列属性配置:
<declare-styleable name="keyboard"> <attr name="xml" format="reference" /> </declare-styleable>
然后是编写自定义软键盘的控件代码了,这里的关键是用自定义的键盘布局替换掉系统默认的键盘布局,自定义代码如下所示:
public class KeyboardLayout extends LinearLayout { private KeyboardView mKeyboardView; private Keyboard mKeyboard; public KeyboardLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initKeyboard(context, attrs); } private void initKeyboard(Context context, AttributeSet attrs){ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.keyboard); if (a.hasValue(R.styleable.keyboard_xml)) { //从xml文件中获取键盘布局 int xmlid = a.getResourceId(R.styleable.keyboard_xml,0); mKeyboard = new Keyboard(context, xmlid); mKeyboardView = (KeyboardView)LayoutInflater.from(context).inflate(R.layout.keyboardview, null); //为键盘视图设置自定义的键盘布局 mKeyboardView.setKeyboard(mKeyboard); mKeyboardView.setEnabled(true); mKeyboardView.setPreviewEnabled(false); addView(mKeyboardView); } } }
最后要给软键盘绑定对应的EditText对象,即当软键盘发生按键动作时,要把按键结果显示在哪个EditText上。这个操作就是调用KeyboardView的setOnKeyboardActionListener方法,设置一个键盘事件监听器,监听器内部主要实现了onKey方法,每当发现合法的按键事件(0-9与退格键),则同步修改EditText对象的文本。这部分代码补充到前面的自定义控件类KeyboardLayout之中:
public void setInputWidget(EditText et) { mKeyboardView.setOnKeyboardActionListener(new KeyboardListener(et)); } private class KeyboardListener implements OnKeyboardActionListener { private EditText et; public KeyboardListener(EditText et) { this.et = et; } @Override public void onKey(int primaryCode, int[] keyCodes) { Editable editable = et.getText(); int start = et.getSelectionStart(); if (primaryCode == Keyboard.KEYCODE_DELETE) { //退格键 if (editable != null && editable.length() > 0) { if (start > 0) { editable.delete(start - 1, start); } } } else if(primaryCode>='0' && primaryCode<='9') { //可以直接输入的字符(如0-9),它们在键盘映射xml中的keycode值必须配置为该字符的ASCII码 editable.insert(start, Character.toString((char) primaryCode)); } } //此处省略其它无需具体实现的Override函数 };
至此我们可以像使用其它控件一样直接把软键盘加入到页面布局啦,注意指定键盘布局的自定义属性:
<com.example.exmtextinput.widget.KeyboardLayout android:id="@+id/kl_input" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" mykeyboard:xml="@xml/inputkeyboard" />
点此查看Android开发笔记的完整目录
__________________________________________________________________________
本文现已同步发布到微信公众号“老欧说安卓”,打开微信扫一扫下面的二维码,或者直接搜索公众号“老欧说安卓”添加关注,更快更方便地阅读技术干货。
作者:aqi00 发表于2017/6/14 9:45:36 原文链接
阅读:0 评论:0 查看评论