前段時間改造了公司的安全鍵盤,是基於Dialog
和Button
自定義的。也所以藉機瞭解下 Android 平臺提供的自定義鍵盤接口。主要有兩個類:Keyboard
和KeyboardView
。很搞笑的是,百度出來自定義Android鍵盤(與自定義Android輸入法不一樣)的文章千篇一概。php
注:這裏講的自定義鍵盤同公司安全鍵盤是兩種實現方式,不存在泄露公司內部技術的問題!!!java
不去吐槽別人,樓主秉持只原創和翻譯的做風,輸出這第50篇博客。相關屬性部分是對照官方文檔和Demo實踐翻譯的,如有瑕疵,請見諒。樓主csdn主頁請點擊flueky專欄。android
序號 | 屬性 | 類型 | 描述 |
---|---|---|---|
1 | keyHeight | dimension/fractional | Key高度,區分精確值(dp、px等)和相對值(%、%p) |
2 | keyWidth | dimension/fractional | Key寬度,同上 |
3 | horizontalGap | dimension/fractional | Key水平間隙,同上 |
4 | verticalGap | dimension/fractional | 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 | keyboardMode | reference | 鍵盤類型,若是該行的類型不符合鍵盤的類型,將跳過該行。 |
6 | rowEdgeFlags | enum | 行邊界標記,top/bottom,鍵盤頂(底)部錨點。 |
序號 | 屬性 | 類型 | 描述 |
---|---|---|---|
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佈局 |
序號 | 屬性 | 類型 | 描述 |
---|---|---|---|
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。請區分
background
和keyBackground
。keyBackground
內容以下:安全
<?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>
複製代碼
效果圖以下:佈局
horizontalGap
和verticalGap
設置。有興趣能夠嘗試下,設置後會出現什麼效果。此處採用drawable
的padding
屬性。keyLabel
屬性只有一個字符時,當作輸入鍵,keyLabel
有多個字符時,若是codes
也有多個值,仍然當作輸入鍵,keyTextSize
值有效;只有一個值時當作功能鍵。labelTextSize
值有效。codes
屬性能夠省略,默認使用keyLabel字符的Unicode值。功能鍵等其餘自定義按鍵的 key code 建議設置爲負數。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;
複製代碼
Shift
鍵須要設置 isSticky
和isModifier
值爲true
, codes
值爲-1。Delete
鍵須要設置isRepeatable
和isModifier
值爲true
,codes
值爲-5。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
,沒有聲明popupLayout
和popupKeyboard
,將會使用默認佈局。只聲明popupLayout
沒聲明popupKeyboard
,popupLayout
無效。