在某些安全性比较高的软件,如银行的相关软件中,输入密码等操作时往往会弹出自定义的软键盘。如果输入的只有数字,开发者往往会通过自定义View和TextView的方式实现,这种方式可以避免第三方键盘的调起。但是如果需要在editview中实现时,就需要实现自己的键盘。
实现自定义键盘主要有两个类:Keyboard和KeyboardView。
Keyboard类主要是用于监听虚拟键盘,它里面有内部类Key和Row,用以记录按键和行的相关信息。KeyBoardView则主要是根据Keyboard中按键的信息,绘制所有的key,同时根据触摸位置,计算出点击的Key,通过OnKeyboardActionListener回调进行事件和string值的传递。
定义KeyboardView
首先要在layout文件夹中定义KeyboardView:
1 2 3 4 5 6 7 8 9 10 11 12 13
| <android.inputmethodservice.KeyboardView android:id="@+id/keyboard" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintTop_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintBottom_toBottomOf="parent" android:keyBackground="@drawable/shape_key_background" android:labelTextSize="15dp" android:keyPreviewHeight="50dp" android:popupLayout="@layout/layout_poplayout" android:keyPreviewLayout="@layout/layout_key_preview"/>
|
这里有几个重要的定义,一个是keyBackground
,这个是按键的背景,一个是 keyPreviewLayout
,这个是按键之后的预览样式,还有一个是popupLayout
,这个是长按之后的预览样式。同时,这里还有一个要注意的是,这边的KeyboardView的id和popupLayout里面的KeyboardView的id一定是android:id="@+id/keyboard"
,不然会无法找到KeyboardView。
自定义键盘的样式Keyboard
定义好KeyboardView之后,需要定义里面具体键盘的样式。在res目录下xml文件夹,当中新建一个xml文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?xml version="1.0" encoding="utf-8"?> <Keyboard xmlns:android="http://schemas.android.com/apk/res/android" android:keyWidth="20%p" android:horizontalGap="1.5%p" android:verticalGap="7dp" android:keyHeight="60dp" > <Row> <Key android:codes="45" android:keyLabel="-" android:keyWidth="15.5%p"/> <Key android:codes="49" android:keyLabel="1"/> <Key android:codes="50" android:keyLabel="2"/> <Key android:codes="51" android:keyLabel="3"/> <Key android:codes="119" android:keyLabel="w" android:popupCharacters="@string/symbol_w" android:popupKeyboard="@layout/layout_poplayout"/> <Key android:codes="8" android:keyIcon="@drawable/key_delete" android:keyWidth="15.5%p" android:isRepeatable="true"/> </Row> ... </Keyboard>
|
里面有KeyboardKeyboard
作为根节点,定义了keyWidth,keyHeight和上下的偏移量。里面有row节点和key节点。key节点和Row节点都可以再次定义相应的行高和宽高,同时,还可以在key中定义其按下的值codes,key显示的值keylabel,key的图标keyIcon,长按的值popupCharacters和长按样式popupKeyboard等属性。里面有一个重要的属性isRepeatable,表示长按后是否有连续点击的效果,比如删除按钮就会有该效果。
定义好键盘的样式后,需要将键盘显示出来,这时就需要定义InputMethodService。
自定义一个类继承InputMethodService,并且实现OnKeyboardActionListener接口。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| public class ZFIme extends InputMethodService implements KeyboardView.OnKeyboardActionListener {
@Override public View onCreateInputView() { keyboardView = (KeyboardView) getLayoutInflater().inflate(R.layout.keyboard, null); mKeyboard = new Keyboard(this, R.xml.keys); keyboardView.setKeyboard(mKeyboard); keyboardView.setOnKeyboardActionListener(this); return keyboardView; }
@Override public void onPress(int primaryCode) {
}
@Override public void onRelease(int primaryCode) {
}
@Override public void onKey(int primaryCode, int[] keyCodes) { getCurrentInputConnection().commitText(Character.toString((char) primaryCode),1); }
@Override public void onText(CharSequence text) {
}
@Override public void swipeLeft() {
}
@Override public void swipeRight() {
}
@Override public void swipeDown() {
}
@Override public void swipeUp() {
} }
|
在onCreateInputView方法中,获取刚才定义的KeyboardView,并且创建keyboard,传入定义好的键盘keys,将keyboard设置给KeyboardView,并且返回。
同时,在onkey方法中将按下的信息传递出去getCurrentInputConnection()方法返回一个InputConnection实例,可以通过它对调起键盘的edittext进行相应的操作,比如文字的输入、删除等。
注册服务
将刚才定义的InputMethodService注册到AndroidManifest中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| //首先要申请绑定输入的权限 <permission android:name="android.permission.BIND_INPUT_METHOD"></permission>
//注册service <service android:name=".ZFIme" android:permission="android.permission.BIND_INPUT_METHOD" > <meta-data android:name="android.view.im" android:resource="@xml/method"/> <intent-filter> <action android:name="android.view.InputMethod" /> </intent-filter> </service>
|
在xml中定义:
1 2 3 4 5 6 7 8 9
| <?xml version="1.0" encoding="utf-8"?> <input-method xmlns:android="http://schemas.android.com/apk/res/android">
<subtype android:label="正风键盘" android:imeSubtypeLocale="english" android:imeSubtypeMode="keyboard"> </subtype> </input-method>
|
到这里为止,我们就可以在设置里面找到自己定义的键盘,在输入时切换到自己的键盘,实现很多自己的功能。但是,从上面的代码可以看到,这些是自定义键盘最基础的步骤,如果需要实现自己的功能,比如整个键盘的背景(系统默认为黑色),自定义的长按功能,多个字符同时在一个key上显示等功能,只是这些是远远不够的,需要定义KeyboardView和Keyboard,至于这些实现这些,请等待后续文章。