工作中遇到了自定义软键盘的场景,虽然简单很快就实现了,但对个别的细节不太满意。
因为细节决定成败,所以细节之处也不能忽视。
先来张效果图吧:
- key的相关属性:
- row的相关属性:
- KeyboardView的相关属性:
- ASCII码对应表:
我对这个自定义软键盘做了个简单的封装,使用起来也很简单。以下是我的自定义软键盘View类:
代码语言:javascript复制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_number
if (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() {
@Override
public void swipeUp() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeDown() {
}
@Override
public void onText(CharSequence text) {
}
@Override
public void onRelease(int primaryCode) {
}
@Override
public void onPress(int primaryCode) {
}
@Override
public 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.2
methodName = "setShowSoftInputOnFocus";
} else if (currentVersion >= 14) {
// 4.0
methodName = "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();
}
}
}
}
布局文件如下:
代码语言:javascript复制<?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>
<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="81"
android:keyLabel="Q" />
<Key
android:codes="87"
android:keyLabel="W" />
<Key
android:codes="69"
android:keyLabel="E" />
<Key
android:codes="82"
android:keyLabel="R" />
<Key
android:codes="84"
android:keyLabel="T" />
<Key
android:codes="89"
android:keyLabel="Y" />
<Key
android:codes="85"
android:keyLabel="U" />
<Key
android:codes="73"
android:keyLabel="I" />
<Key
android:codes="79"
android:keyLabel="O" />
<Key
android:codes="80"
android:keyLabel="P" />
</Row>
<!--第三行-->
<Row>
<Key
android:codes="65"
android:keyLabel="A" />
<Key
android:codes="83"
android:keyLabel="S" />
<Key
android:codes="68"
android:keyLabel="D" />
<Key
android:codes="70"
android:keyLabel="F" />
<Key
android:codes="71"
android:keyLabel="G" />
<Key
android:codes="72"
android:keyLabel="H" />
<Key
android:codes="74"
android:keyLabel="J" />
<Key
android:codes="75"
android:keyLabel="K" />
<Key
android:codes="76"
android:keyLabel="L" />
<Key
android:codes="-1"
android:keyIcon="@drawable/btn_ok"
android:keyHeight="190dp" />
</Row>
<!--第四行-->
<Row>
<Key
android:codes="90"
android:keyLabel="Z" />
<Key
android:codes="88"
android:keyLabel="X" />
<Key
android:codes="67"
android:keyLabel="C" />
<Key
android:codes="86"
android:keyLabel="V" />
<Key
android:codes="66"
android:keyLabel="B" />
<Key
android:codes="78"
android:keyLabel="N" />
<Key
android:codes="77"
android:keyLabel="M" />
<Key
android:codes="-3"
android:isRepeatable="false"
android:keyIcon="@drawable/btn_del"
android:keyWidth="330dp"/>
</Row>
</Keyboard>
使用也很简单:
代码语言:javascript复制 mainBinding.includeBackscreenSearchLayout.edtInputPhone.setOnTouchListener(new View.OnTouchListener() {
@Override
public 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;
}
});