Android自定義鍵盤的實(shí)現(xiàn)(數(shù)字鍵盤和字母鍵盤)
在項(xiàng)目中,產(chǎn)品對(duì)于輸入方式會(huì)有特殊的要求,需要對(duì)輸入方式增加特定的限制,這就需要采用自定義鍵盤。本文主要講述數(shù)字鍵盤和字母鍵盤的自定義實(shí)現(xiàn)。
項(xiàng)目地址:https://github.com/xudjx/djkeyboard
鍵盤效果:

自定義鍵盤的實(shí)現(xiàn)步驟如下:
- 自定義CustomKeyboard, 繼承自系統(tǒng)Keyboard,實(shí)現(xiàn)KeyboardView.OnKeyboardActionListener相關(guān)接口,以處理用戶的點(diǎn)擊回調(diào);
- 自定義CustomKeyboardView, 繼承自KeyboardView,實(shí)現(xiàn)自定義鍵盤繪制;
- 創(chuàng)建KeyboardManager, 用于處理自定義鍵盤的顯示以及和輸入U(xiǎn)I的交互
自定義CustomKeyboard
Android系統(tǒng)Keyboard的構(gòu)造方法如下:
/**
* Creates a keyboard from the given xml key layout file.
* @param context the application or service context
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
*/
public Keyboard(Context context, int xmlLayoutResId) {
this(context, xmlLayoutResId, 0);
}
/**
* Creates a keyboard from the given xml key layout file. Weeds out rows
* that have a keyboard mode defined but don't match the specified mode.
* @param context the application or service context
* @param xmlLayoutResId the resource file that contains the keyboard layout and keys.
* @param modeId keyboard mode identifier
* @param width sets width of keyboard
* @param height sets height of keyboard
*/
public Keyboard(Context context, @XmlRes int xmlLayoutResId, int modeId, int width,
int height) {
...
}
其中,參數(shù)xmlLayoutResId是必須的,另外還可以通過(guò)計(jì)算系統(tǒng)鍵盤的高度來(lái)設(shè)定自定義鍵盤的高度。
xmlLayoutRes的格式如下:
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard android:keyWidth="24.9%p"
android:keyHeight="49dp"
android:horizontalGap="0.1333%p"
android:verticalGap="1px"
xmlns:android="http://schemas.android.com/apk/res/android">
<Row>
<Key android:codes="49" android:keyEdgeFlags="left"
android:keyLabel="1" />
<Key android:codes="50" android:keyLabel="2" />
<Key android:codes="51" android:keyLabel="3" />
<Key android:codes="-5" android:iconPreview="@drawable/key_num_del_bg"
android:isRepeatable="true"/>
</Row>
...
</Keyboard>
詳細(xì)的數(shù)字鍵盤和字母鍵盤xmlLayoutRes資源文件可以從以下鏈接獲?。?br />
數(shù)字鍵盤xmlLayoutRes
字母鍵盤xmlLayoutRes
CustomKeyboard主要目的就是賦予xmlLayoutRes并實(shí)現(xiàn)特定按鍵的點(diǎn)擊處理,其主要重載的方法是onKey(int primaryCode, int[] keyCodes)。詳細(xì)代碼如下:
public abstract class BaseKeyboard extends Keyboard implements KeyboardView.OnKeyboardActionListener{
@Override
public void onKey(int primaryCode, int[] keyCodes) {
if(null != mEditText && mEditText.hasFocus() && !handleSpecialKey(primaryCode)) {
Editable editable = mEditText.getText();
int start = mEditText.getSelectionStart();
int end = mEditText.getSelectionEnd();
if (end > start){
editable.delete(start,end);
}
if(primaryCode == KEYCODE_DELETE) {
if(!TextUtils.isEmpty(editable)) {
if(start > 0) {
editable.delete(start-1,start);
}
}
}else if(primaryCode == getKeyCode(R.integer.hide_keyboard)){
hideKeyboard();
}else {
editable.insert(start,Character.toString((char) primaryCode));
}
}
}
public abstract boolean handleSpecialKey(int primaryCode);
}
如上所示是BaseKeyboard,數(shù)字鍵盤和字母鍵盤需要繼承它,并實(shí)現(xiàn)public abstract boolean handleSpecialKey(int primaryCode)方法。
自定義CustomKeyboardView
KeyboardView 是承載不同的keyboard并繪制keyboard, 是鍵盤布局的繪制板, 并與系統(tǒng)交互。通過(guò)繼承KeyboardView自定義CustomKeyboardView,可以對(duì)按鍵樣式實(shí)現(xiàn)自定義??疾霮eyboardView的源碼,發(fā)現(xiàn)其UI樣式都是private類型,這就需要通過(guò)反射的方式獲取特定的UI屬性,并重新進(jìn)行賦值,同時(shí)重載onDraw()方法,在onDraw()中重新繪制。
詳細(xì)代碼可以參考github源碼: BaseKeyBoardView源碼
自定義鍵盤的UI效果如下:

數(shù)字鍵盤

字母鍵盤
創(chuàng)建KeyboardManager
主要處理以下功能邏輯:
- 綁定EditText和Keyboard,監(jiān)聽(tīng)EditText的OnFocusChangeListener,處理鍵盤彈出和鍵盤掩藏;
- 處理系統(tǒng)鍵盤和自定義鍵盤之間的切換關(guān)系;
- 處理鍵盤區(qū)域其他自定義view的顯示,比如需要讓鍵盤自動(dòng)搜索功能時(shí),可在manager中進(jìn)行相關(guān)處理
以綁定EditText為例:
public void bindToEditor(EditText editText, BaseKeyboard keyboard) {
hideSystemSoftKeyboard(editText);
editText.setTag(R.id.bind_keyboard_2_editor, keyboard);
if (keyboard.getKeyStyle() == null) {
keyboard.setKeyStyle(mDefaultKeyStyle);
}
editText.setOnFocusChangeListener(editorFocusChangeListener);
}
private final View.OnFocusChangeListener editorFocusChangeListener = new View.OnFocusChangeListener() {
@Override
public void onFocusChange(final View v, boolean hasFocus) {
if (v instanceof EditText) {
if (hasFocus) {
v.postDelayed(new Runnable() {
@Override
public void run() {
showSoftKeyboard((EditText) v);
}
},300);
} else {
hideSoftKeyboard();
}
}
}
};
public void showSoftKeyboard(EditText editText) {
mRootView.addOnLayoutChangeListener(mOnLayoutChangeListener);
BaseKeyboard keyboard = getBindKeyboard(editText);
if (keyboard == null) {
Log.e(TAG, "edit text not bind to keyboard");
return;
}
keyboard.setEditText(editText);
keyboard.setNextFocusView(mKeyboardWithSearchView.getEditText());
initKeyboard(keyboard);
...
}
鍵盤的使用方式非常簡(jiǎn)單, 通過(guò)KeyboardManager實(shí)現(xiàn)調(diào)用
數(shù)字鍵盤:
KeyboardManager keyboardManagerNumber = new KeyboardManager(this); keyboardManagerNumber.bindToEditor(editText2, new NumberKeyboard(context,NumberKeyboard.DEFAULT_NUMBER_XML_LAYOUT));
字母鍵盤:
KeyboardManager keyboardManagerAbc = new KeyboardManager(this); keyboardManagerAbc.bindToEditor(editText1, new ABCKeyboard(context, ABCKeyboard.DEFAULT_ABC_XML_LAYOUT));
至此,自定義鍵盤的實(shí)現(xiàn)就介紹完了,文中介紹的更多還是實(shí)現(xiàn)的思路,具體實(shí)現(xiàn)可以參考github,有需要的用戶也可以直接修改項(xiàng)目的源碼。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android編程監(jiān)聽(tīng)APK安裝與刪除等過(guò)程的方法
這篇文章主要介紹了Android編程監(jiān)聽(tīng)APK安裝與刪除等過(guò)程的方法,涉及Android事件監(jiān)聽(tīng)、權(quán)限控制、廣播操作等相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-10-10
Android實(shí)現(xiàn)網(wǎng)易新聞客戶端側(cè)滑菜單(2)
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)網(wǎng)易新聞客戶端側(cè)滑菜單第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11
Android實(shí)現(xiàn)Tab布局的4種方式(Fragment+TabPageIndicator+ViewPager)
Android現(xiàn)在實(shí)現(xiàn)Tab類型的界面方式越來(lái)越多,本文詳細(xì)介紹了Android實(shí)現(xiàn)Tab布局的4種方式,具有一定的參考價(jià)值,有興趣的可以了解一下。2016-11-11
android判斷點(diǎn)擊位置是否在扇形區(qū)域內(nèi)
這篇文章主要為大家詳細(xì)介紹了android判斷點(diǎn)擊位置是否在扇形區(qū)域內(nèi),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
在Android中使用SQLite數(shù)據(jù)庫(kù)及其操作詳解
在?Android?開(kāi)發(fā)中,使用?SQLite?數(shù)據(jù)庫(kù)是一種常見(jiàn)的持久化數(shù)據(jù)存儲(chǔ)方式,本文將通過(guò)代碼示例詳細(xì)講解如何在?Android?中創(chuàng)建數(shù)據(jù)庫(kù)表、插入數(shù)據(jù)、執(zhí)行查詢操作以及驗(yàn)證查詢結(jié)果,需要的朋友可以參考下2024-08-08
Android TimePicker 直接輸入的問(wèn)題解決方案
這篇文章主要介紹了Android TimePicker 直接輸入的問(wèn)題解決方案的相關(guān)資料,需要的朋友可以參考下2017-04-04
Android同時(shí)安裝Release和Debug版本的方法
這篇文章主要介紹了Android同時(shí)安裝Release和Debug版本的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12

