android监听软键盘退格(删除)事件
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.InputCon
·
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.
* <p>
* <p><b>Caveat:</b> 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}.</p>
*
* @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"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1">
<cn.deerlands.deerland.mvp.ui.wiget.TEditText
android:id="@+id/identify1"
android:layout_width="55dp"
android:layout_height="55dp"
android:layout_centerInParent="true"
android:digits="@string/input_regular"
android:background="@drawable/identify_back"
android:gravity="center"
android:inputType="number"
android:textStyle="bold"
android:maxLength="1"
android:textColor="@color/colorLaunchText"
android:textSize="20sp" />
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
调用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;//不处理当前退格
};
更多推荐
已为社区贡献5条内容
所有评论(0)