android监听软键盘退格(删除)事件
16lz
2021-12-04
android监听软键盘退格(删除)事件
package cn.deerlands.deerland.mvp.ui.util;import android.view.KeyEvent;import android.view.View;import android.view.inputmethod.InputConnection;import android.view.inputmethod.InputConnectionWrapper;/** * Created by tu zhen yu on 2017/12/1. * {@link InputConnection} 是输入法和View交互的纽带。 * {@link InputConnectionWrapper} 是 InputConnection 的代理类,可以代理EditText的InputConnection,监听和拦截软键盘的各种输入事件。 * 注:用 {@link View#setOnKeyListener(View.OnKeyListener)} 监听软键盘的按键点击事件对有些键盘无效(比如谷歌输入法), * 最好用InputConnection去监听。 */public class TInputConnection extends InputConnectionWrapper { private BackspaceListener mBackspaceListener; /** * Initializes a wrapper. * *
Caveat: Although the system can accept {@code (InputConnection) null} in some * places, you cannot emulate such a behavior by non-null {@link InputConnectionWrapper} that * has {@code null} in {@code target}.
* * @param target the {@link InputConnection} to be proxied. * @param mutable set {@code true} to protect this object from being reconfigured to target * another {@link InputConnection}. Note that this is ignored while the target is {@code null}. */ public TInputConnection(InputConnection target, boolean mutable) { super(target, mutable); } public interface BackspaceListener { /** * @return true 代表消费了这个事件 * */ boolean onBackspace(); } /** * 当软键盘删除文本之前,会调用这个方法通知输入框,我们可以重写这个方法并判断是否要拦截这个删除事件。 * 在谷歌输入法上,点击退格键的时候不会调用{@link #sendKeyEvent(KeyEvent event)}, * 而是直接回调这个方法,所以也要在这个方法上做拦截; * */ @Override public boolean deleteSurroundingText(int beforeLength, int afterLength) { if(mBackspaceListener != null){ if(mBackspaceListener.onBackspace()){ return true; } } return super.deleteSurroundingText(beforeLength, afterLength); } public void setBackspaceListener(BackspaceListener backspaceListener) { this.mBackspaceListener = backspaceListener; } /** * 当在软件盘上点击某些按钮(比如退格键,数字键,回车键等),该方法可能会被触发(取决于输入法的开发者), * 所以也可以重写该方法并拦截这些事件,这些事件就不会被分发到输入框了 * */ @Override public boolean sendKeyEvent(KeyEvent event) { if( event.getKeyCode() == KeyEvent.KEYCODE_DEL && event.getAction() == KeyEvent.ACTION_DOWN){ if(mBackspaceListener != null && mBackspaceListener.onBackspace()){ return true; } } return super.sendKeyEvent(event); }}
editText class
package cn.deerlands.deerland.mvp.ui.wiget;import android.content.Context;import android.util.AttributeSet;import android.view.inputmethod.EditorInfo;import android.view.inputmethod.InputConnection;import androidx.appcompat.widget.AppCompatEditText;import cn.deerlands.deerland.mvp.ui.util.TInputConnection;/** * Created by tuzhenyu on 2017/12/21. */public class TEditText extends AppCompatEditText { private TInputConnection inputConnection; public TEditText(Context context) { super(context); init(); } public TEditText(Context context, AttributeSet attrs) { super(context, attrs); init(); } public TEditText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } private void init() { inputConnection = new TInputConnection(null, true); } /** * 当输入法和EditText建立连接的时候会通过这个方法返回一个InputConnection。 * 我们需要代理这个方法的父类方法生成的InputConnection并返回我们自己的代理类。 */ @Override public InputConnection onCreateInputConnection(EditorInfo outAttrs) { inputConnection.setTarget(super.onCreateInputConnection(outAttrs)); return inputConnection; } public void setBackSpaceLisetener(TInputConnection.BackspaceListener backSpaceLisetener) { inputConnection.setBackspaceListener(backSpaceLisetener); }}
使用
xml文件
<?xml version="1.0" encoding="utf-8"?>
调用class 文件(简单说如 事件分发 return true处理当前退格事件,被用户消耗;return false不处理当前退格事件,交给系统)
TEditText identify1; private void init() { identify1 = findViewById(R.id.identify1); identify1.setBackSpaceLisetener(backspaceListener); } TInputConnection.BackspaceListener backspaceListener = () -> { if (currentFocusEdit != null && TextUtils.isEmpty(currentFocusEdit.getText().toString())) { //当前获取焦点的 editText不为空 按返回使上一个框获取焦点 int indexEdit = -1; for (int i = 0; i < editTexts.size(); i++) { if (i > 0 && editTexts.get(i).equals(currentFocusEdit)) { indexEdit = i; break; } } if (indexEdit != -1) { //找到了需要获取焦点的按钮 for (int i = 0; i < editTexts.size(); i++) { TEditText tEditText = editTexts.get(i); if (indexEdit == i) { //当前退格失去焦点 loseFocusable(tEditText,false); } if (indexEdit - 1 == i) { //退格后获得焦点 if (currentCode.size() != 0) currentCode.remove(currentCode.size() - 1); tEditText.setText(""); loseFocusable(tEditText,true); } } return true;//表示处理当前退格事件 } } return false;//不处理当前退格 };
更多相关文章
- Android(安卓)之不要滥用 SharedPreferences(下)
- Android:实现无标题的两种方法
- 去掉RecycleView或者ListView上下滑动阴影的方法
- android 去掉顶部状态栏
- Android(安卓)数据库之 SQLiteConnectionPool 源码分析
- BitmapFactory.Options学习笔记
- Android面试题整理(中)
- android中点击事件的4种写法
- android 4.0中的Fragment