工作中遇到了自定义软键盘的场景,虽然简单很快就实现了,但对个别的细节不太满意。
因为细节决定成败,所以细节之处也不能忽视。
先来张效果图吧:
- key的相关属性:
- row的相关属性:
- KeyboardView的相关属性:
- ASCII码对应表:
我对这个自定义软键盘做了个简单的封装,使用起来也很简单。以下是我的自定义软键盘View类:
package com.newcapec.visitorsystem.diyview;import android.app.Activity;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.text.InputType;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.EditText;import com.newcapec.cardliarbry.VistorCardController;
import com.newcapec.visitorsystem.R;
import com.newcapec.visitorsystem.interf.OnFinishListener;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;/*** @author : xieqinzhong* @date :2020/6/16 14:52* @description:**/
public class AbcNumberView extends View {private Activity mActivity;private MyKeyboardView mKeyboardView;private EditText mEdit;/*** 数字与大写字母键盘*/private Keyboard numberKeyboard;/** 确认回调*/private OnFinishListener finishListener;private KeyboardView keyboardView;/** id: 布局id**/public AbcNumberView(int viewId,Activity activity,boolean includeNumber, EditText edit,OnFinishListener finishListener) {super(activity);mActivity = activity;mEdit = edit;this.finishListener = finishListener;//R.xml.abc_and_numberif (includeNumber) {numberKeyboard = new Keyboard(activity, R.xml.abc_and_number);}else {numberKeyboard = new Keyboard(activity, R.xml.abc_key);}mKeyboardView = (MyKeyboardView) activity.findViewById(viewId);mKeyboardView.setKeyboard(numberKeyboard);mKeyboardView.setEnabled(true);mKeyboardView.setPreviewEnabled(false);mKeyboardView.setOnKeyboardActionListener(listener);mKeyboardView.bringToFront();}private KeyboardView.OnKeyboardActionListener listener = new KeyboardView.OnKeyboardActionListener() {@Overridepublic void swipeUp() {}@Overridepublic void swipeRight() {}@Overridepublic void swipeLeft() {}@Overridepublic void swipeDown() {}@Overridepublic void onText(CharSequence text) {}@Overridepublic void onRelease(int primaryCode) {}@Overridepublic void onPress(int primaryCode) {}@Overridepublic void onKey(int primaryCode, int[] keyCodes) {Editable editable = mEdit.getText();int start = mEdit.getSelectionStart();//判定是否是中文的正则表达式 [\\u4e00-\\u9fa5]判断一个中文 [\\u4e00-\\u9fa5]+多个中文if (primaryCode == -1) {// 确定键hideKeyboard();beginSearch(finishListener,mEdit.getText().toString());} else if (primaryCode == -3) {//删除键if (editable != null && editable.length() > 0) {if (start > 0) {editable.delete(start - 1, start);}}}else {editable.insert(start, Character.toString((char) primaryCode));}}};private void beginSearch(final OnFinishListener onFinishListener, String value) {finishListener.search(value);}/*** 软键盘展示状态*/public boolean isShow() {return mKeyboardView.getVisibility() == View.VISIBLE;}/*** 软键盘展示*/public void showKeyboard() {int visibility = mKeyboardView.getVisibility();if (visibility == View.GONE || visibility == View.INVISIBLE) {mKeyboardView.setVisibility(View.VISIBLE);}}/*** 软键盘隐藏*/public void hideKeyboard() {int visibility = mKeyboardView.getVisibility();if (visibility == View.VISIBLE) {mKeyboardView.setVisibility(View.INVISIBLE);}}/*** 禁掉系统软键盘*/public void hideSoftInputMethod() {mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);int currentVersion = android.os.Build.VERSION.SDK_INT;String methodName = null;if (currentVersion >= 16) {// 4.2methodName = "setShowSoftInputOnFocus";} else if (currentVersion >= 14) {// 4.0methodName = "setSoftInputShownOnFocus";}if (methodName == null) {mEdit.setInputType(InputType.TYPE_NULL);} else {Class<EditText> cls = EditText.class;Method setShowSoftInputOnFocus;try {setShowSoftInputOnFocus = cls.getMethod(methodName, boolean.class);setShowSoftInputOnFocus.setAccessible(true);setShowSoftInputOnFocus.invoke(mEdit, false);} catch (NoSuchMethodException e) {mEdit.setInputType(InputType.TYPE_NULL);e.printStackTrace();} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {e.printStackTrace();}}}}
布局文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"android:horizontalGap="10px"android:keyWidth="160dp"android:keyHeight="90dp"android:verticalGap="1%p"><!--第一行--><Row><Keyandroid:codes="49"android:keyLabel="1" /><Keyandroid:codes="50"android:keyLabel="2" /><Keyandroid:codes="51"android:keyLabel="3" /><Keyandroid:codes="52"android:keyLabel="4" /><Keyandroid:codes="53"android:keyLabel="5" /><Keyandroid:codes="54"android:keyLabel="6" /><Keyandroid:codes="55"android:keyLabel="7" /><Keyandroid:codes="56"android:keyLabel="8" /><Keyandroid:codes="57"android:keyLabel="9" /><Keyandroid:codes="48"android:keyEdgeFlags="right"android:keyLabel="0" /></Row><!--第二行--><Row><Keyandroid:codes="81"android:keyLabel="Q" /><Keyandroid:codes="87"android:keyLabel="W" /><Keyandroid:codes="69"android:keyLabel="E" /><Keyandroid:codes="82"android:keyLabel="R" /><Keyandroid:codes="84"android:keyLabel="T" /><Keyandroid:codes="89"android:keyLabel="Y" /><Keyandroid:codes="85"android:keyLabel="U" /><Keyandroid:codes="73"android:keyLabel="I" /><Keyandroid:codes="79"android:keyLabel="O" /><Keyandroid:codes="80"android:keyLabel="P" /></Row><!--第三行--><Row><Keyandroid:codes="65"android:keyLabel="A" /><Keyandroid:codes="83"android:keyLabel="S" /><Keyandroid:codes="68"android:keyLabel="D" /><Keyandroid:codes="70"android:keyLabel="F" /><Keyandroid:codes="71"android:keyLabel="G" /><Keyandroid:codes="72"android:keyLabel="H" /><Keyandroid:codes="74"android:keyLabel="J" /><Keyandroid:codes="75"android:keyLabel="K" /><Keyandroid:codes="76"android:keyLabel="L" /><Keyandroid:codes="-1"android:keyIcon="@drawable/btn_ok"android:keyHeight="190dp" /></Row><!--第四行--><Row><Keyandroid:codes="90"android:keyLabel="Z" /><Keyandroid:codes="88"android:keyLabel="X" /><Keyandroid:codes="67"android:keyLabel="C" /><Keyandroid:codes="86"android:keyLabel="V" /><Keyandroid:codes="66"android:keyLabel="B" /><Keyandroid:codes="78"android:keyLabel="N" /><Keyandroid:codes="77"android:keyLabel="M" /><Keyandroid:codes="-3"android:isRepeatable="false"android:keyIcon="@drawable/btn_del"android:keyWidth="330dp"/></Row></Keyboard>
使用也很简单:
mainBinding.includeBackscreenSearchLayout.edtInputPhone.setOnTouchListener(new View.OnTouchListener() {@Overridepublic boolean onTouch(View view, MotionEvent event) {if (event.getAction() == MotionEvent.ACTION_UP) {abcNumberViewb.setOkListener(edtInputPhoneOkListener);abcNumberViewb.setmEdit( mainBinding.includeBackscreenSearchLayout.edtInputPhone);if(!abcNumberViewb.isShow()){abcNumberViewb.showKeyboard();}}return false;}});