尊重勞動(dòng)者創(chuàng)作,轉(zhuǎn)發(fā)請(qǐng)注明出處
首先看本文實(shí)現(xiàn)的效果。

學(xué)而不思則罔,思而不學(xué)則殆。一眨眼五一小長(zhǎng)假就結(jié)束了,完全沒(méi)玩嗨呢,不能完全進(jìn)入工作狀態(tài),小伙伴們扶我起來(lái)嗨。一年嗨兩次,一次嗨半年。好了,言歸正傳,今天是一個(gè)自定義鍵盤。
首先了解 API
- KeyboardView
- Keyboard
KeyboardView
KeyboardView 一個(gè)用于呈現(xiàn)虛擬鍵盤的 view,同時(shí)處理著每一個(gè)鍵盤所對(duì)應(yīng)的點(diǎn)擊、觸摸等事件。
常用屬性:
| XML attributes | ||
|---|---|---|
| android:keyBackground | Image for the key. | |
| android:keyPreviewLayout | Layout resource for key press feedback. | |
| android:keyPreviewOffset | Vertical offset of the key press feedback from the key. | |
| android:keyTextColor | Color to use for the label in a key. | |
| android:keyTextSize | Size of the text for character keys. | |
| android:labelTextSize | Size of the text for custom keys with some text and no icon. | |
| android:popupLayout | Layout resource for popup keyboards. | |
| android:verticalCorrection | Amount to offset the touch Y coordinate by, for bias correction. |
顧名思義這些 API 很簡(jiǎn)單,這里不做過(guò)多的解釋。在使用時(shí)我們需要特別注意下 android:verticalCorrection 。由于 android 設(shè)備眾多,鍵盤 y 軸觸摸區(qū)域可能存在偏差,此 API 是用于矯正偏移的 Y 坐標(biāo)。具體作用自己可以在 xml 手動(dòng)更改進(jìn)行感受。
Keyboard
Keyboard 的樣式是以 XML 文件的形式存在的,由多個(gè) Row 和 Key 組成,我們可以直接在 XML 定義鍵盤的行、鍵、以及鍵大小,下面看代碼塊。
<Keyboard
android:keyWidth="%10p"
android:keyHeight="50px"
android:horizontalGap="2px"
android:verticalGap="2px" >
<Row android:keyWidth="32px" >
<Key android:keyLabel="A" />
...
</Row>
...
</Keyboard>
其中 Keyboard 表示整個(gè)鍵盤, Row 表示其中一行,Key 表示某一個(gè)具體按鍵。也就是說(shuō)鍵盤的大小,樣式都可以在這個(gè)文件中進(jìn)行定義,下面通過(guò)一個(gè)表格對(duì) Keyboard 必要屬性進(jìn)行簡(jiǎn)單了解。
| XML attributes | |
|---|---|
| android:horizontalGap | Default horizontal gap between keys. |
| android:keyHeight | Default height of a key, in pixels or percentage of display width. |
| android:keyWidth | Default width of a key, in pixels or percentage of display width. |
| android:verticalGap | Default vertical gap between rows of keys. |
OK,到這里自定義鍵盤所需要了解的知識(shí)已經(jīng)足夠了,下面進(jìn)入編碼模式。
public class KeyboardViewS implements OnKeyboardActionListener {
private static final int KEYBOARD_DURATION = 350;
private EditText mEditText;
private Keyboard mKeyboard;
/** 是否大寫 */
private boolean isUperCase = false;
private android.inputmethodservice.KeyboardView keyboardView;
public KeyboardViewS(Activity act, EditText edit) {
this.mEditText = edit;
mKeyboard = new Keyboard(act, R.xml.qwerty);
keyboardView = (android.inputmethodservice.KeyboardView) (act.findViewById(R.id.keyboard_view));
keyboardView.setKeyboard(mKeyboard);
/** 設(shè)置沒(méi)有彈窗的提示 */
keyboardView.setPreviewEnabled(false);
keyboardView.setOnKeyboardActionListener(this);
uperCase();
}
@Override
public void onKey(int primaryCode, int[] keyCodes) {
Editable editable = mEditText.getText();
int start = mEditText.getSelectionStart();
if (primaryCode == Keyboard.KEYCODE_CANCEL) { // 完成
hideKeyboard(keyboardView);
} else if (primaryCode == Keyboard.KEYCODE_DELETE) {// 回退
if (editable != null && editable.length() > 0) {
if (start > 0) {
editable.delete(start - 1, start);
}
}
} else if (primaryCode == Keyboard.KEYCODE_SHIFT) {// 大小寫切換
uperCase();
keyboardView.setKeyboard(mKeyboard);
} else if (primaryCode == 57419) {
if (start > 0) {
mEditText.setSelection(start - 1);
}
} else if (primaryCode == 57421) {
if (start < mEditText.length()) {
mEditText.setSelection(start + 1);
}
} else {
editable.insert(start, Character.toString((char) primaryCode));
}
}
/** 鍵盤大小寫切換 */
private void uperCase() {
final List<Key> keylist = mKeyboard.getKeys();
if (isUperCase) {
isUperCase = false;
for (Key key : keylist) {
if (key.label != null && isword(key.label.toString())) {
key.label = key.label.toString().toLowerCase();
key.codes[0] = key.codes[0] + 32;
}
}
} else {
isUperCase = true;
for (Key key : keylist) {
if (key.label != null && isword(key.label.toString())) {
key.label = key.label.toString().toUpperCase();
key.codes[0] = key.codes[0] - 32;
}
}
}
}
/** 隱藏輸入法,顯示光標(biāo) */
public static void setSystemInputGone(EditText editText) {
if (Build.VERSION.SDK_INT >= 11) {
Class<EditText> cls = EditText.class;
try {
Method setShowSoftInputOnFocus = cls.getMethod("setShowSoftInputOnFocus", boolean.class);
setShowSoftInputOnFocus.setAccessible(false);
setShowSoftInputOnFocus.invoke(editText, false);
} catch (Exception e) {
e.printStackTrace();
}
} else {
editText.setInputType(android.text.InputType.TYPE_NULL);
editText.setInputType(editText.getInputType());
}
}
/** 顯示鍵盤 */
public void showKeyboard() {
int visibility = keyboardView.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
Animation anim = AnimationUtils.translateAnimationOut(KEYBOARD_DURATION);
keyboardView.setVisibility(View.VISIBLE);
keyboardView.startAnimation(anim);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
super.onAnimationEnd(animation);
keyboardView.clearAnimation();
}
});
}
}
/** 隱藏鍵盤 */
public static void hideKeyboard(final KeyboardView keyboardView) {
if (keyboardView == null) {
return;
}
if (keyboardView.getVisibility() == View.VISIBLE) {
Animation anim = AnimationUtils.translateAnimationIn(KEYBOARD_DURATION);
keyboardView.startAnimation(anim);
anim.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
super.onAnimationEnd(animation);
keyboardView.clearAnimation();
}
});
keyboardView.setVisibility(View.GONE);
}
}
private boolean isword(String str) {
final String wordstr = "abcdefghijklmnopqrstuvwxyz";
if (wordstr.indexOf(str.toLowerCase()) > -1) {
return true;
}
return false;
}
...
}
核心代碼。尊重勞動(dòng)者成功,轉(zhuǎn)發(fā)請(qǐng)注明出處。
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard android:keyWidth="8.4%" android:keyHeight="7%"
android:horizontalGap="5dp" android:verticalGap="3dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<Row>
<Key android:codes="49" android:keyLabel="1" />
<Key android:codes="50" android:keyLabel="2" />
<Key android:codes="51" android:keyLabel="3" />
<Key android:codes="52" android:keyLabel="4" />
<Key android:codes="53" android:keyLabel="5" />
<Key android:codes="54" android:keyLabel="6" />
<Key android:codes="55" android:keyLabel="7" />
<Key android:codes="56" android:keyLabel="8" />
<Key android:codes="57" android:keyLabel="9" />
<Key android:codes="48" android:keyEdgeFlags="right" android:keyLabel="0" />
</Row>
<Row>
<Key android:codes="113" android:keyEdgeFlags="left" android:keyLabel="q" />
<Key android:codes="119" android:keyLabel="w" />
<Key android:codes="101" android:keyLabel="e" />
<Key android:codes="114" android:keyLabel="r" />
<Key android:codes="116" android:keyLabel="t" />
<Key android:codes="121" android:keyLabel="y" />
<Key android:codes="117" android:keyLabel="u" />
<Key android:codes="105" android:keyLabel="i" />
<Key android:codes="111" android:keyLabel="o" />
<Key android:codes="112" android:keyEdgeFlags="right" android:keyLabel="p" />
</Row>
<Row>
<Key android:horizontalGap="6%p" android:codes="97" android:keyEdgeFlags="left" android:keyLabel="a" />
<Key android:codes="115" android:keyLabel="s" />
<Key android:codes="100" android:keyLabel="d" />
<Key android:codes="102" android:keyLabel="f" />
<Key android:codes="103" android:keyLabel="g" />
<Key android:codes="104" android:keyLabel="h" />
<Key android:codes="106" android:keyLabel="j" />
<Key android:codes="107" android:keyLabel="k" />
<Key android:codes="108" android:keyEdgeFlags="right" android:keyLabel="l" />
</Row>
<Row>
<Key android:keyWidth="13%p" android:codes="-1" android:keyEdgeFlags="left" android:isModifier="true" android:isSticky="true" android:keyIcon="@drawable/shift" />
<Key android:codes="122" android:keyLabel="z"/>
<Key android:codes="120" android:keyLabel="x"/>
<Key android:codes="99" android:keyLabel="c" />
<Key android:codes="118" android:keyLabel="v"/>
<Key android:codes="98" android:keyLabel="b" />
<Key android:codes="110" android:keyLabel="n"/>
<Key android:codes="109" android:keyLabel="m"/>
<Key android:keyWidth="13.3%p" android:codes="-5" android:keyEdgeFlags="right" android:isRepeatable="true" android:keyIcon="@drawable/keyboard_delete" />
</Row>
<Row android:rowEdgeFlags="bottom">
<Key android:keyWidth="15%p" android:codes="-6" android:keyLabel="復(fù)制"/>
<Key android:keyWidth="15%p" android:codes="-6" android:keyLabel="粘貼"/>
<Key android:keyWidth="44%p" android:codes="32" android:isRepeatable="true" android:keyLabel="~~ 楊柯 ~~" />
<Key android:keyWidth="17.5%p" android:codes="-3" android:keyEdgeFlags="right" android:keyLabel="完成" />
</Row>
</Keyboard>
再堅(jiān)持一下,再努力一下,再前進(jìn)一下,也許,成功離你只有一步之遙。有句話說(shuō),哪怕只有百分之一的希望,我也要付出百分之百的努力。學(xué)習(xí)不能停?。?/strong>
** ps: 有幫助的話: 喜歡、評(píng)論、轉(zhuǎn)發(fā),動(dòng)一動(dòng)你的小手讓更多的人知道!關(guān)注 帥比-楊**