手记

自定义Android键盘

前言

前段时间改造了公司的安全键盘是基于DialogButton自定义的。也因此借机了解下 Android 平台提供的自定义键盘接口。主要有两个类KeyboardKeyboardView。很搞笑的是百度出来自定义Android键盘与自定义Android输入法不同的文章千篇一律。

注这里讲的自定义键盘同公司安全键盘是两种实现方式不存在泄露公司内部技术的问题

不去吐槽别人楼主秉持只原创和翻译的作风输出这第50篇博客。相关属性部分是对照官方文档和Demo实践翻译的若有瑕疵请见谅。楼主csdn主页请点击flueky专栏

相关属性

Keyboard

序号属性类型描述
1keyHeightdimension/fractionalKey高度区分精确值dp、px等和相对值%、%p
2keyWidthdimension/fractionalKey宽度同上
3horizontalGapdimension/fractionalKey水平间隙同上
4verticalGapdimension/fractionalKey按键间隙垂直同上

Row

序号属性类型描述
1keyHeightdimension/fractionalKey高度区分精确值dp、px等和相对值%、%p
2keyWidthdimension/fractionalKey宽度同上
3horizontalGapdimension/fractionalKey水平间隙同上
4verticalGapdimension/fractionalKey按键间隙垂直同上
5keyboardModereference键盘类型如果该行的类型不符合键盘的类型将跳过该行。
6rowEdgeFlagsenum行边界标记top/bottom键盘顶底部锚点。

Key

序号属性类型描述
1keyHeightdimension/fractionalKey高度区分精确值dp、px等和相对值%、%p
2keyWidthdimension/fractionalKey宽度同上
3horizontalGapdimension/fractionalKey水平间隙同上
4verticalGapdimension/fractionalKey按键间隙垂直同上
5codesintKey输出符号对应的Unicode值官方还说支持字转义字符串不明白。
6iconPreviewreference弹出回显的icon
7isModifierboolean是否功能修饰键如Alt/Shift
8isStickyboolean是否是开关键
9isRepeatableboolean是否允许重复。true表示长按时重复执行。
10keyEdgeFlagsenumKey边缘位置标记left/right键盘左右边锚点。
11keyIconreference替换label显示在按键上的icon。
12keyLabelreference显示在Key上的标签。
13keyOutputTextstringKey按下时输出的字符或字符串。
14popupCharactersstring小键盘显示的字符用于显示Key候选项。
15popupKeyboardreference按键候选小键盘的keyboard布局

KeyboardView

序号属性类型描述
1keyBackgroundreference按键的图像背景必须包含多个状态的drawable
2verticalCorrectiondimension补充触摸y坐标的偏移用于偏差矫正
3keyPreviewLayoutreference按键按下时预览框的布局
4keyPreviewOffsetdimension按键按下时预览框的偏移。>0 向下<0 向上。
5keyPreviewHeightdimension按键按下时预览框的高度。
6keyTextSizedimension按键文字大小。
7keyTextColorcolor按键文字颜色。
8labelTextSizedimension标签文字大小,keylabel有多个字符且keycodes只有一个值时该属性生效。
9popupLayoutreference按键候选小键盘的KeyboardView布局。
10shadowRadiusfloat按键文字阴影半径
11shadowColorcolor按键文字阴影颜色

自定义键盘

布局

<android.inputmethodservice.KeyboardView
    android:id="@+id/activity_main_keyboard"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#212121"
    android:keyBackground="@drawable/key_bg"
    android:keyTextColor="#dddddd"
    android:keyTextSize="18sp"
    android:labelTextSize="18sp"
    android:paddingBottom="2dp"
    android:paddingTop="2dp" />

键盘容器视图Demo中直接放在Activity布局。KeyboardView可以显示不同类型的Keyboard。请区分backgroundkeyBackgroundkeyBackground内容如下

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- 此处设置key边距 -->
    <item
        android:bottom="2dp"
        android:left="2dp"
        android:right="2dp"
        android:top="2dp">
        <selector>
            <!-- 按压后图层 -->
            <item android:state_pressed="true">
                <shape>
                    <solid android:color="#565656" />
                    <corners android:radius="5dp" />
                </shape>
            </item>
            <!-- 正常状态图层 -->
            <item>
                <shape>
                    <solid android:color="#383838" />
                    <corners android:radius="5dp" />
                </shape>
            </item>
        </selector>
    </item></layer-list>

字母键盘布局

<?xml version="1.0" encoding="utf-8"?><Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyHeight="50dp"
    android:keyWidth="10%p">
    <Row android:rowEdgeFlags="top">
        <Key
            android:keyEdgeFlags="left"
            android:keyLabel="q" />
        <Key android:keyLabel="w" />
        <Key android:keyLabel="e" />
        <Key android:keyLabel="r" />
        <Key android:keyLabel="t" />
        <Key android:keyLabel="y" />
        <Key android:keyLabel="u" />
        <Key android:keyLabel="i" />
        <Key android:keyLabel="o" />
        <Key
            android:keyEdgeFlags="right"
            android:keyLabel="p" />
    </Row>
    <Row>
        <Key
            android:codes="97"
            android:horizontalGap="5%p"
            android:keyEdgeFlags="left"
            android:keyLabel="a" />
        <Key android:keyLabel="s" />
        <Key android:keyLabel="d" />
        <Key android:keyLabel="f" />
        <Key android:keyLabel="g" />
        <Key android:keyLabel="h" />
        <Key android:keyLabel="j" />
        <Key android:keyLabel="k" />
        <Key
            android:keyEdgeFlags="right"
            android:keyLabel="l" />
    </Row>
    <Row>
        <Key
            android:codes="-1"
            android:isModifier="true"
            android:isSticky="true"
            android:keyEdgeFlags="left"
            android:keyIcon="@drawable/key_caps_lock_icon"
            android:keyWidth="15%p" />
        <Key android:keyLabel="z" />
        <Key android:keyLabel="x" />
        <Key android:keyLabel="c" />
        <Key android:keyLabel="v" />
        <Key android:keyLabel="b" />
        <Key android:keyLabel="n" />
        <Key android:keyLabel="m" />

        <Key
            android:codes="-5"
            android:isModifier="true"
            android:isRepeatable="true"
            android:keyEdgeFlags="right"
            android:keyIcon="@drawable/key_delete_icon"
            android:keyWidth="15%p" />
    </Row>

    <Row android:rowEdgeFlags="bottom">
        <Key
            android:codes="-11"
            android:keyEdgeFlags="left"
            android:keyLabel="123"
            android:keyWidth="15%p" />
        <Key
            android:codes="32"
            android:isRepeatable="true"
            android:keyLabel=" "
            android:keyWidth="70%p" />
        <Key
            android:codes="-12"
            android:keyEdgeFlags="right"
            android:keyLabel="#+="
            android:keyWidth="15%p" />
    </Row></Keyboard>

效果图如下

数字键盘布局

<?xml version="1.0" encoding="utf-8"?><Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:keyHeight="50dp"
    android:keyWidth="33.3%p">
    <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="ABC" />
        <Key
            android:codes="48"
            android:keyLabel="0" />
        <Key
            android:codes="-12"
            android:keyLabel="#+=" />
    </Row></Keyboard>

效果图如下

  1. Key之间的间隙不建议使用horizontalGapverticalGap 设置。有兴趣可以尝试下设置后会出现什么效果。此处采用drawablepadding属性。

  2. keyLabel属性只有一个字符时当做输入键keyLabel有多个字符时如果codes也有多个值仍然当做输入键keyTextSize 值有效只有一个值时当做功能键。labelTextSize值有效。

  3. codes 属性可以省略默认使用keyLabel字符的Unicode值。功能键等其他自定义按键的 key code 建议设置为负数。

  4. codes有多个值时单击取第一个双击取第二个三连击取第三个。通常建议该属性值不要超过3个。多个值用逗号分隔。

## 逻辑

final Keyboard pinyin26KB = new Keyboard(this, R.xml.pinyin_26);// 字母键盘final Keyboard numberKB = new Keyboard(this, R.xml.number); // 数字键盘keyboardView.setKeyboard(pinyin26KB); // 设置默认显示字符键盘keyboardView.setOnKeyboardActionListener(new KeyboardView.OnKeyboardActionListener() {   // 按下 key 时执行
   @Override
   public void onPress(int primaryCode) {
       Log.d(TAG, "onPress: "+primaryCode);
   }   // 释放 key 时执行
   @Override
   public void onRelease(int primaryCode) {
       Log.d(TAG, "onRelease: "+primaryCode);
   }   // 点击 key 时执行
   @Override
   public void onKey(int primaryCode, int[] keyCodes) {
       Editable editable = edtInput.getText();       int start = edtInput.getSelectionStart();       switch (primaryCode) {           case Keyboard.KEYCODE_SHIFT:// 设置shift状态然后刷新页面
               pinyin26KB.setShifted(!pinyin26KB.isShifted());
               keyboardView.invalidateAllKeys();               break;           case Keyboard.KEYCODE_DELETE:// 点击删除键长按连续删除
               if (editable != null && editable.length() > 0 && start > 0) {
                   editable.delete(start - 1, start);
               }               break;           case -10:// 自定义code切换到拼音键盘
               keyboardView.setKeyboard(pinyin26KB);               break;           case -11:// 自定义code切换到字母键盘
               keyboardView.setKeyboard(numberKB);               break;           case -12:// 自定义code
               // 切换到符号键盘待实现
               break;           default:// 数值code
               if (primaryCode >= 97 && primaryCode <= 97 + 26) {// 按下字母键
                   editable.insert(start, pinyin26KB.isShifted() ? Character.toString((char) (primaryCode - 32)) : Character.toString((char) (primaryCode)));
               } else {// 其他code值转字符在输入框中显示
                   editable.insert(start, Character.toString((char) (primaryCode)));
               }               break;
       }
   }   // 设置了 keyOutputText 属性后执行。
   @Override
   public void onText(CharSequence text) {
       Log.d(TAG, "onText: "+text);
   }
});

已经定义的功能键code值如下

   public static final int KEYCODE_SHIFT = -1;   public static final int KEYCODE_MODE_CHANGE = -2;   public static final int KEYCODE_CANCEL = -3;   public static final int KEYCODE_DONE = -4;   public static final int KEYCODE_DELETE = -5;   public static final int KEYCODE_ALT = -6;
  1. Shift键需要设置 isStickyisModifier 值为true codes值为-1。<br/>

  2. Delete键需要设置isRepeatableisModifier 值为truecodes值为-5。<br/>

  3. 切换键盘的功能键需要自定义上述中未用到的code值在onKey方法中做好对应的处理。

回显

keyboardView.setPreviewEnabled(true);

打开回显默认是true。

android:keyPreviewLayout="@layout/preview"
android:keyPreviewHeight="50dp"
android:keyPreviewOffset="-20dp"

在键盘容器中声明以上属性。

备选小键盘

pupop_layout.xml 备选小键盘容器

<?xml version="1.0" encoding="utf-8"?><android.inputmethodservice.KeyboardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/keyboardView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#212121"
    android:keyBackground="@drawable/popup_bg"
    android:keyPreviewHeight="60dp"
    android:keyPreviewLayout="@layout/preview"
    android:keyPreviewOffset="-10dp"
    android:keyTextColor="#dddddd"
    android:keyTextSize="18sp"
    android:labelTextSize="18sp" />

pupop.xml 备选小键盘视图

<?xml version="1.0" encoding="utf-8"?><Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/popup_bg"
    android:keyHeight="50dp">

    <Row>
        <Key android:codes="97" />

        <Key android:codes="98" />

        <Key android:codes="99" />
    </Row></Keyboard>

w键添加备选功能

<Key
    android:keyLabel="w"
    android:popupCharacters="123"
    android:popupKeyboard="@layout/pupop" />

在键盘容器中指定备选小键盘布局

android:popupLayout="@layout/pupop_layout"

如果只声明了popupCharacters没有声明popupLayoutpopupKeyboard,将会使用默认布局。只声明popupLayout没声明popupKeyboardpopupLayout无效。

原文链接http://www.apkbus.com/blog-953354-77623.html

0人推荐
随时随地看视频
慕课网APP