
一、在xml文件夹中创建keyboard.xml文件
- 主要属性:
- android:keyWidth 按键宽度
- android:keyHeight
- android:horizontalGap 按键间的水平空隙
- android:verticalGap
- android:keyLabel 按键显示内容
<?xml version="1.0" encoding="utf-8"?>
<!-- 设置键盘宽高、间隙-->
<Keyboard xmlns:android="http://schemas.android.***/apk/res/android"
android:keyHeight="50dp"
android:keyWidth="25%"
android:horizontalGap="1dp"
android:verticalGap="1dp"
>
<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="-5" android:keyLabel="删除" />
</Row>
<Row>
<Key android:codes="52" android:keyLabel="4"/>
<Key android:codes="53" android:keyLabel="5"/>
<Key android:codes="54" android:keyLabel="6"/>
<Key android:codes="-4" android:keyLabel="确定" android:keyHeight="152dp"/>
</Row>
<Row>
<Key android:codes="55" android:keyLabel="7"/>
<Key android:codes="56" android:keyLabel="8"/>
<Key android:codes="57" android:keyLabel="9"/>
<!-- 新增透明占位键,凑齐4列 -->
<Key android:codes="-100" android:keyLabel=""
android:keyHeight="0dp" android:keyBackground="@android:color/transparent"/>
</Row>
<Row>
<Key android:codes="-3" android:keyLabel="清零"/>
<Key android:codes="48" android:keyLabel="0"/>
<Key android:codes="46" android:keyLabel="."/>
<Key android:codes="-100" android:keyLabel=""
android:keyHeight="0dp" android:keyBackground="@android:color/transparent"/>
</Row>
</Keyboard>
二、创建KeyboardUtil工具类
- 说明:
- 构造方法传入:KeyboardView、EditText
-
构造方法内部
- 根据 EdiText上下文、keyboard.xml(键盘样式)文件 生成 Keyboard
- 工具类中的成员变量KeyboardView 设定Keyboard
- this.keyboardView.setEnabled(true);//设定键盘的可交互性
- this.keyboardView.setPreviewEnabled(false); //关闭键盘按键点击放大预览
- this.keyboardView.setOnKeyboardActionListener() //键盘按键点击监听(在onKey中判断点击的按键即可)
-
回调接口 onEnsureListerner 抽象方法 onEnsure( ) 点击确认键的 业务实现方法
- 为什么使用接口?在本工具类里面难以实现某种方法,依赖于代码环境,所以使用接口,并添加暂未实现的抽象方法,等到了合适的代码环境(使用工具类时)再 实现该方法
- 接口一般伴随着接口初始化方法一同出现 就比如例子里的 setOnEnsureListener(),用来提供实现接口重写抽象方法
-
onKey方法是如何操作EditText的
-
获取Editable对象 Editable editable = editText.getText();
-
获取光标位置 int start = editText.getSelectionStart();
-
删除 判空 && 判Editable对象长度>0 && 光标位置是否>0 在使用editable.delete(start-1,start);删除光标前一位
-
清空 editable.clear( );
-
打开、隐藏 键盘视图
- 判断键盘视图打开状态,再调用keyboardView.setVisbility( )即可
package ***.example.tally.utils;
import android.content.Context;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
import android.text.Editable;
import android.text.InputType;
import android.view.View;
import android.widget.EditText;
import ***.example.tally.R;
public class KeyboardUtil {
// 自定义键盘
private final Keyboard keyboard;
private KeyboardView keyboardView;
private EditText editText;
public interface OnEnsureListener{
public void onEnsure();
}
OnEnsureListener onEnsureListener;
public void setOnEnsureListener(OnEnsureListener onEnsureListener) {
this.onEnsureListener = onEnsureListener;
}
public KeyboardUtil(KeyboardView keyboardView, EditText editText) {
this.keyboardView = keyboardView;
this.editText = editText;
//输入框要取消自动弹出系统键盘
this.editText.setInputType(InputType.TYPE_NULL);
// 自定义键盘需要绑定 自定义键盘xml文件、EditText上下文
keyboard = new Keyboard(this.editText.getContext(), R.xml.keyboard);
//将系统键盘视图设置为 自定义键盘
this.keyboardView.setKeyboard(keyboard);
this.keyboardView.setEnabled(true);
this.keyboardView.setPreviewEnabled(false);
this.keyboardView.setOnKeyboardActionListener(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 = editText.getText();
int start = editText.getSelectionStart();
switch (primaryCode){
// 点击删除
case Keyboard.KEYCODE_DELETE:
//判断输入框是否有文本
if (editable!=null&&editable.length()>0) {
//判断输入光标位置
if(start>0){
editable.delete(start-1,start);
}
}
break;
// 点击确定
case Keyboard.KEYCODE_DONE:
onEnsureListener.onEnsure();
break;
// 点击清零
case Keyboard.KEYCODE_CANCEL:
editable.clear();
break;
// 其他按键
default:
// insert方法在editable 对应光标位置插入文本 (char)primaryCode将ascii码转为字符
editable.insert(start,Character.toString((char)primaryCode));
break;
}
}
@Override
public void onText(CharSequence text) {
}
@Override
public void swipeLeft() {
}
@Override
public void swipeRight() {
}
@Override
public void swipeDown() {
}
@Override
public void swipeUp() {
}
});
}
public void showKeyboard(){
int visibility =keyboardView.getVisibility();
if (visibility== View.GONE||visibility==View.INVISIBLE) {
keyboardView.setVisibility(View.VISIBLE);
}
}
public void hideKeyboard(){
int visibility = keyboardView.getVisibility();
if (visibility== View.VISIBLE||visibility==View.INVISIBLE) {
keyboardView.setVisibility(View.GONE);
}
}
}
三、布局文件使用KeyboardView
-
必备属性:
-
android:focusable="true" 可获取焦点的键盘视图,能够获取后续Keyboardutil传入 的editText 焦点
-
android:focusableInTouchMode="true" 触摸模式获取焦点
<android.inputmethodservice.KeyboardView
android:id="@+id/kv_key_board"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:keyBackground="@color/grey_backgroud"
android:keyTextColor="@color/black"
android:paddingTop="2dp"
android:shadowColor="@color/black"
android:shadowRadius="0.0" />
四、使用KeyboardUtil工具类
//显示键盘
KeyboardUtil keyboardUtil = new KeyboardUtil(keyboardView,et_fragment_edit);
keyboardUtil.showKeyboard();
//设置键盘监听器接口
keyboardUtil.setOnEnsureListener(new KeyboardUtil.OnEnsureListener() {
@Override
//点击键盘 使用 接口的ensure方法
public void onEnsure() {
//获取输入消息(账单类型、账单名称、账单金额、账单备注、账单时间),存入数据库
//账单类型、账单名称 通过Application 的infoMap 获取支出列表 的A***ountTypeinfo
//将得到的 信息 储存 到A***ountDetailInfo对象中,再通过 数据库的 insertA***ountDetailInfo保存
A***ountTypeInfo a***ountTypeInfo = MyApplication.infoMap.get(MyApplication.KEY_OUT***E_LIST)
.get(out***eAdapter.selection);
int a***ountType =a***ountTypeInfo.type;
String a***ountName = a***ountTypeInfo.typeName;
String a***ountM = et_fragment_edit.getText().toString();
String a***ountTip = tv_tip.getText().toString();
String a***ountTime = tv_time.getText().toString();
double a***ountMoney ;
//对 账单金额进行判空
if(a***ountM.isEmpty()){
ToastUtil.showToast(getContext(),"请输入账单金额");
return;
}
a***ountMoney = Double.parseDouble(a***ountM);
A***ountDetailInfo a***ountDetailInfo =new A***ountDetailInfo(
a***ountType,a***ountName,a***ountMoney,a***ountTime,a***ountTip
);
TallyOpenDBHelper tDBHelper =TallyOpenDBHelper.getInstance(getContext());
tDBHelper.insertA***ountDetailInfo(a***ountDetailInfo);
//返回上一页
finishActivity();
ToastUtil.showToast(getContext(),"数据添加成功");
}
});