自定義Android鍵盤

前言

前段時間改造了公司的安全鍵盤,是基於DialogButton自定義的。也所以藉機瞭解下 Android 平臺提供的自定義鍵盤接口。主要有兩個類:KeyboardKeyboardView。很搞笑的是,百度出來自定義Android鍵盤(與自定義Android輸入法不一樣)的文章千篇一概。php

注:這裏講的自定義鍵盤同公司安全鍵盤是兩種實現方式,不存在泄露公司內部技術的問題!!!java

不去吐槽別人,樓主秉持只原創和翻譯的做風,輸出這第50篇博客。相關屬性部分是對照官方文檔和Demo實踐翻譯的,如有瑕疵,請見諒。樓主csdn主頁請點擊flueky專欄android

相關屬性

Keyboard

序號 屬性 類型 描述
1 keyHeight dimension/fractional Key高度,區分精確值(dp、px等)和相對值(%、%p)
2 keyWidth dimension/fractional Key寬度,同上
3 horizontalGap dimension/fractional Key水平間隙,同上
4 verticalGap dimension/fractional Key按鍵間隙(垂直),同上

Row

序號 屬性 類型 描述
1 keyHeight dimension/fractional Key高度,區分精確值(dp、px等)和相對值(%、%p)
2 keyWidth dimension/fractional Key寬度,同上
3 horizontalGap dimension/fractional Key水平間隙,同上
4 verticalGap dimension/fractional Key按鍵間隙(垂直),同上
5 keyboardMode reference 鍵盤類型,若是該行的類型不符合鍵盤的類型,將跳過該行。
6 rowEdgeFlags enum 行邊界標記,top/bottom,鍵盤頂(底)部錨點。

Key

序號 屬性 類型 描述
1 keyHeight dimension/fractional Key高度,區分精確值(dp、px等)和相對值(%、%p)
2 keyWidth dimension/fractional Key寬度,同上
3 horizontalGap dimension/fractional Key水平間隙,同上
4 verticalGap dimension/fractional Key按鍵間隙(垂直),同上
5 codes int Key輸出符號對應的Unicode值,官方還說支持字轉義字符串,不明白。
6 iconPreview reference 彈出回顯的icon
7 isModifier boolean 是否功能修飾鍵,如:Alt/Shift
8 isSticky boolean 是不是開關鍵
9 isRepeatable boolean 是否容許重複。true表示長按時重複執行。
10 keyEdgeFlags enum Key邊緣位置標記,left/right,鍵盤左(右)邊錨點。
11 keyIcon reference 替換label顯示在按鍵上的icon。
12 keyLabel reference 顯示在Key上的標籤。
13 keyOutputText string Key按下時輸出的字符或字符串。
14 popupCharacters string 小鍵盤顯示的字符,用於顯示Key候選項。
15 popupKeyboard reference 按鍵候選小鍵盤的keyboard佈局

KeyboardView

序號 屬性 類型 描述
1 keyBackground reference 按鍵的圖像背景,必須包含多個狀態的drawable
2 verticalCorrection dimension 補充觸摸y座標的偏移,用於誤差矯正
3 keyPreviewLayout reference 按鍵按下時預覽框的佈局
4 keyPreviewOffset dimension 按鍵按下時預覽框的偏移。>0 向下,<0 向上。
5 keyPreviewHeight dimension 按鍵按下時預覽框的高度。
6 keyTextSize dimension 按鍵文字大小。
7 keyTextColor color 按鍵文字顏色。
8 labelTextSize dimension 標籤文字大小,keylabel有多個字符且keycodes只有一個值時,該屬性生效。
9 popupLayout reference 按鍵候選小鍵盤的KeyboardView佈局。
10 shadowRadius float 按鍵文字陰影半徑
11 shadowColor color 按鍵文字陰影顏色

自定義鍵盤

佈局

<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>
複製代碼

效果圖以下:ide

數字鍵盤佈局

<?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值,以下:this

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鍵須要設置 isSticky和isModifier 值爲truecodes值爲-1。
  2. Delete鍵須要設置isRepeatableisModifier 值爲truecodes值爲-5。
  3. 切換鍵盤的功能鍵須要自定義上述中未用到的code值,在onKey方法中作好對應的處理。

回顯

keyboardView.setPreviewEnabled(true);
複製代碼

打開回顯,默認是true。spa

android:keyPreviewLayout="@layout/preview"
android:keyPreviewHeight="50dp"
android:keyPreviewOffset="-20dp"
複製代碼

在鍵盤容器中聲明以上屬性。.net

備選小鍵盤

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無效。

相關文章
相關標籤/搜索