前言
這個是富文本寫的霍殴,代碼看起來很亂,請移步http://www.reibang.com/p/b1973de976e4
正文
對于自定義鍵盤匆瓜,官方提供了兩個玩意(再簡單的鍵盤也都要用到):Keyboard和KeyboardView,當然,為了方便我們會定義一個util:KeyboardUtil
Keyboard
Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard consists of rows of keys.
加載鍵盤的XML描述并存儲鍵的屬性章姓。鍵盤由一行鍵組成。(還有翻譯识埋,我真貼心)
第一個重點就在這凡伊,你的鍵只能按官方指示一行一行進行放置。為什么窒舟?沒有為什么不信看下去系忙。
keyboard是一個xml文件,下面有個例子:
具體描述如下:
實例為三列四行標準格式惠豺,接下來聊一聊標準:最標準的莫過于每個鍵同樣的高度同樣的寬度银还,當然這是很理想的一種形式风宁。我們一般會得到UI強制規(guī)定的個性化鍵盤
不同顏色的自定義鍵下面說別著急,對于上面這樣的不規(guī)則鍵盤蛹疯,因為只能一行一行放置鍵戒财,
所以首先keyWidth我們設置為25%p我們一行最多要放四個鍵,一三行我們放四個鍵二四行放三個鍵捺弦,第一三行最后一個鍵高度為其他鍵高度的兩倍需要在<key />里面單獨寫keyHeight宋渔,同理如果鍵寬不一樣的話單獨設置即可川梅。
KeyboardView
A view that renders a virtual Keyboard. It handles rendering of keys and detecting key presses and touch movements.
呈現(xiàn)虛擬鍵盤的視圖蝇更。它處理按鍵的渲染和檢測按鍵和觸摸動作遵蚜。
這個東西就是寫在布局里的view了
示例如下:
這是我重寫掉的,后面會講寞钥。
具體屬性如下:
android:shadowRadius="0.0"? android:shadowColor="背景色"
這兩個屬性可以解決鍵盤上顯示的文字糊的問題慌申。
KeyboardUtil
public class KeyboardUtil {
????private Viewll_jianpan;
????private KeyboardViewmKeyboardView;
????private KeyboardmNumberKeyboard;// 數(shù)字鍵盤
? ? private KeyboardmLetterKeyboard;// 字母鍵盤
? ? private ContextmContext;
????private boolean isNumber =false;// 是否數(shù)字鍵盤
? ? private boolean isUpper =false;// 是否大寫
? ? private EditTextmEditText;
? ? public KeyboardUtil(Context context, View view, EditText editText,int type) {
? ? ????mContext=context;
????????mEditText = editText;
????????mLetterKeyboard =new Keyboard(context, R.xml.keyboard_qwerty);
????????mKeyboardView = (KeyboardView) view.findViewById(R.id.keyboard_view);
????????ll_jianpan= view.findViewById(R.id.ll_jianpan);
????????ImageView iv_close= (ImageView)ll_jianpan.findViewById(R.id.iv_close);
????????iv_close.setOnClickListener(new View.OnClickListener() {
????????????@Override
? ? ? ? ? ? public void onClick(View view) {
????????????????hideKeyboard();
????????????}
????????});
????????if (type==0){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers_blank);
????????}else if (type==1){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers);
????????}else if (type==2){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers_realname);
????????}else if (type==66299){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers_blank);
????????iv_close.setVisibility(View.GONE);
????????}
????????mKeyboardView.setKeyboard(mNumberKeyboard);
????????mKeyboardView.setEnabled(true);
????????mKeyboardView.setPreviewEnabled(false);
????????mKeyboardView.setOnKeyboardActionListener(listener);
}
public KeyboardUtil(Context context, Activity activity, EditText editText,int type) {
????mContext=context;
????mEditText = editText;
????if (type==0){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers_blank);
????}else if (type==1){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers);
????}else if (type==2){
????????mNumberKeyboard =new Keyboard(context, R.xml.keyboard_numbers_realname);
????}
????????mLetterKeyboard =new Keyboard(context, R.xml.keyboard_qwerty);
????????mKeyboardView = (KeyboardView) activity.findViewById(R.id.keyboard_view);
????????ll_jianpan= activity.findViewById(R.id.ll_jianpan);
????????mKeyboardView.setKeyboard(mNumberKeyboard);
????????mKeyboardView.setEnabled(true);
????????mKeyboardView.setPreviewEnabled(false);
????????mKeyboardView.setOnKeyboardActionListener(listener);
????????ImageView iv_close= (ImageView)ll_jianpan.findViewById(R.id.iv_close);
????????iv_close.setOnClickListener(new View.OnClickListener() {
????????????@Override
? ? ? ? ? ? public void onClick(View view) {
????????????????hideKeyboard();
????????}
????});
}
????private KeyboardView.OnKeyboardActionListenerlistener =new KeyboardView.OnKeyboardActionListener() {
????@Override
? ? ? ? public void onPress(int primaryCode) {}
????@Override
? ? ? ? public void onRelease(int primaryCode) {}
????@Override
? ? ? ? public void onKey(int primaryCode,int[] keyCodes) {
????????????Editable editable =mEditText.getText();
????????????int start =mEditText.getSelectionStart();
? ? ? ? ? ? if (primaryCode == Keyboard.KEYCODE_CANCEL||primaryCode ==66299) ????????????{// cancel
? ? ? ? ? ? ? ? hideKeyboard();
????????????}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) {// 大小寫切換
? ? ? ? ? ? ? ? changeKeyboart();
mKeyboardView.setKeyboard(mLetterKeyboard);
}else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {// 數(shù)字與字母鍵盤互換
? ? ? ? ? ? ? ? if (isNumber) {
isNumber =false;
mKeyboardView.setKeyboard(mLetterKeyboard);
}else {
isNumber =true;
mKeyboardView.setKeyboard(mNumberKeyboard);
}
}else if (primaryCode ==57419) {// 左移
? ? ? ? ? ? ? ? if (start >0) {
mEditText.setSelection(start -1);
}
}else if (primaryCode ==57419) {// 右移
? ? ? ? ? ? ? ? if (start >mEditText.length()) {
mEditText.setSelection(start +1);
}
}else {// 輸入鍵盤值
? ? ? ? ? ? ? ? editable.insert(start, Character.toString((char) primaryCode));
}
}
@Override
? ? ? ? public void onText(CharSequence text) {}
@Override
? ? ? ? public void swipeLeft() {}
@Override
? ? ? ? public void swipeRight() {}
@Override
? ? ? ? public void swipeDown() {}
@Override
? ? ? ? public void swipeUp() {}
};
private void changeKeyboart() {
List keyList =mLetterKeyboard.getKeys();
if (isUpper) {// 大寫切換小寫
? ? ? ? ? ? isUpper =false;
for (Keyboard.Key key : keyList) {
if (key.label !=null && isLetter(key.label.toString())) {
key.label = key.label.toString().toLowerCase();
key.codes[0] = key.codes[0] +32;
}}}else {// 小寫切換成大寫
? ? ? ? ? ? isUpper =true;
for (Keyboard.Key key : keyList) {
if (key.label !=null && isLetter(key.label.toString())) {
key.label = key.label.toString().toUpperCase();
key.codes[0] = key.codes[0] -32;}}}}
/**
* 判斷是否是字母
*/
? ? private boolean isLetter(String str) {
String wordStr ="abcdefghijklmnopqrstuvwxyz";
return wordStr.contains(str.toLowerCase());
}
public void hideKeyboard() {
int visibility =ll_jianpan.getVisibility();
if (visibility == View.VISIBLE) {
ll_jianpan.startAnimation(AnimationUtils.loadAnimation(mContext,R.anim.anim_bottom_out));
ll_jianpan.setVisibility(View.GONE);
}}
public void showKeyboard() {
int visibility =ll_jianpan.getVisibility();
if (visibility == View.GONE || visibility == View.INVISIBLE) {
ll_jianpan.startAnimation(AnimationUtils.loadAnimation(mContext,R.anim.anim_bottom_in));
ll_jianpan.setVisibility(View.VISIBLE);}}}
有點亂將就看。理郑。蹄溉。ll_jianpan其實就是一個包含keyboradview的線性布局
在這里比較重要的就是實現(xiàn)鍵盤的監(jiān)聽OnKeyboardActionListener
下面有一張對應表code對應ASCII值? 然后輸出的就是控制字符?
當然我們肯定需要自定義一些功能,如關閉鍵盤切換數(shù)字字母鍵盤左移右移等您炉,這些都放在了OnKeyboardActionListener的onKey中柒爵。其實就是根據(jù)不同的code處理不同的事件,自定義code盡量個性點防止跟已占用code發(fā)生沖突邻吭。
既然是自定義鍵盤餐弱,我們當然要阻攔系統(tǒng)鍵盤,方法如下
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
????你的輸入框.setShowSoftInputOnFocus(false);
}else {
????你的輸入框.setInputType(InputType.TYPE_NULL);
}
PS:setInputType(InputType.TYPE_NULL)會讓輸入框失去光標囱晴,但是沒辦法21以下的沒有setShowSoftInputOnFocus(false)這方法膏蚓。
至于打開鍵盤,可以在觸摸輸入框的時候觸發(fā)也可直接觸發(fā)
輸入框.setOnTouchListener(new View.OnTouchListener() {
????@Override
? ? public boolean onTouch(View view, MotionEvent motionEvent) {
? ? ? new KeyboardUtil(context,Activity.this,輸入框,0).showKeyboard();
????????return false;
????}
});
最后畸写,重寫的Keyboradview
public class MyKeyboredViewextends KeyboardView {
????public MyKeyboredView(Context context, AttributeSet attrs) {
????????super(context, attrs);
????}
????public MyKeyboredView(Context context, AttributeSet attrs,int defStyleAttr) {
????????super(context, attrs, defStyleAttr);
????}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
????public MyKeyboredView(Context context, AttributeSet attrs,int defStyleAttr,int ????defStyleRes) {
????????super(context, attrs, defStyleAttr, defStyleRes);
????}
@Override
? ? public void onDraw(Canvas canvas) {
????????super.onDraw(canvas);
????????List keys = getKeyboard().getKeys();
????????for (Keyboard.Key key : keys) {
????????if (key.codes[0] ==66299) {
????????Log.e("KEY","Drawing key with code " + key.codes[0]);
????????Drawable dr = (Drawable)? ????????getInstance().getResources().getDrawable(R.drawable.jianpan_sure);
????????dr.setBounds(key.x, key.y, key.x + key.width, key.y + key.height);
????????dr.draw(canvas);
}else {}}}}
重寫onDraw()根據(jù)code把點九圖充滿指定的鍵即可
下圖的確認鍵:
后記
看到這你可能在找demo源碼驮瞧,不好意思沒有的,如果你的時間確實很緊請移步枯芬,如果你還有點時間论笔,一天自己學完寫完沒什么問題的,歡迎提出問題千所,我們一起學習狂魔。