Android自定義鍵盤的實現(xiàn)(數(shù)字鍵盤和字母鍵盤)
在項目中,產(chǎn)品對于輸入方式會有特殊的要求,需要對輸入方式增加特定的限制,這就需要采用自定義鍵盤。本文主要講述數(shù)字鍵盤和字母鍵盤的自定義實現(xiàn)。
項目地址:https://github.com/xudjx/djkeyboard
鍵盤效果:
自定義鍵盤的實現(xiàn)步驟如下:
- 自定義CustomKeyboard, 繼承自系統(tǒng)Keyboard,實現(xiàn)KeyboardView.OnKeyboardActionListener相關(guān)接口,以處理用戶的點擊回調(diào);
- 自定義CustomKeyboardView, 繼承自KeyboardView,實現(xiàn)自定義鍵盤繪制;
- 創(chuàng)建KeyboardManager, 用于處理自定義鍵盤的顯示以及和輸入UI的交互
自定義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是必須的,另外還可以通過計算系統(tǒng)鍵盤的高度來設(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資源文件可以從以下鏈接獲取:
數(shù)字鍵盤xmlLayoutRes
字母鍵盤xmlLayoutRes
CustomKeyboard主要目的就是賦予xmlLayoutRes并實現(xià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ù)字鍵盤和字母鍵盤需要繼承它,并實現(xiàn)public abstract boolean handleSpecialKey(int primaryCode)方法。
自定義CustomKeyboardView
KeyboardView 是承載不同的keyboard并繪制keyboard, 是鍵盤布局的繪制板, 并與系統(tǒng)交互。通過繼承KeyboardView自定義CustomKeyboardView,可以對按鍵樣式實現(xiàn)自定義??疾霮eyboardView的源碼,發(fā)現(xiàn)其UI樣式都是private類型,這就需要通過反射的方式獲取特定的UI屬性,并重新進行賦值,同時重載onDraw()方法,在onDraw()中重新繪制。
詳細(xì)代碼可以參考github源碼: BaseKeyBoardView源碼
自定義鍵盤的UI效果如下:
數(shù)字鍵盤
字母鍵盤
創(chuàng)建KeyboardManager
主要處理以下功能邏輯:
- 綁定EditText和Keyboard,監(jiān)聽EditText的OnFocusChangeListener,處理鍵盤彈出和鍵盤掩藏;
- 處理系統(tǒng)鍵盤和自定義鍵盤之間的切換關(guān)系;
- 處理鍵盤區(qū)域其他自定義view的顯示,比如需要讓鍵盤自動搜索功能時,可在manager中進行相關(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); ... }
鍵盤的使用方式非常簡單, 通過KeyboardManager實現(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));
至此,自定義鍵盤的實現(xiàn)就介紹完了,文中介紹的更多還是實現(xiàn)的思路,具體實現(xiàn)可以參考github,有需要的用戶也可以直接修改項目的源碼。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章

Android點擊EditText文本框之外任何地方隱藏鍵盤的解決辦法

新版Android Studio3.6找不到R.java怎么處理

Android string-array數(shù)據(jù)源簡單使用