Android 监听软件盘的删除键

1,091 阅读1分钟

方法一:通过android.view.View#setOnKeyListener来实现键盘按键监听,如下:

editText.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (keyCode == KeyEvent.KEYCODE_DEL) {
                // 按下了删除键
                return true;
            }

            if (keyCode == KeyEvent.KEYCODE_ENTER) {
                return true;
            }
        }
        return false;
    }
});

缺点:按系统软键盘的删除键时,并不一定每次都会触发删除事件的回调。

方案二:自定义EditText并重写onCreateInputConnection方法,拦截删除的监听,如下

package com.zw.windowsubdewmo;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText ;

/**
 * @author zw
 */
public class MyKeyEditText extends AppCompatEditText {

    private static final String TAG = "MyKeyEditText";

    public MyKeyEditText(@NonNull Context context) {
        super(context);
    }

    public MyKeyEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyKeyEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {
        Log.i(TAG, "dispatchKeyEvent:---- "+event.getKeyCode());
        return super.dispatchKeyEvent(event);
    }


    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        return new BackspaceInputConnection(super.onCreateInputConnection(outAttrs), true);
    }

    private class BackspaceInputConnection extends InputConnectionWrapper {

        public BackspaceInputConnection(InputConnection target, boolean mutable) {
            super(target, mutable);
        }

        /**
         * 当软键盘删除文本之前,会调用这个方法通知输入框,我们可以重写这个方法并判断是否要拦截这个删除事件。
         * 在谷歌输入法上,点击退格键的时候不会调用{@link #sendKeyEvent(KeyEvent event)},
         * 而是直接回调这个方法,所以也要在这个方法上做拦截;
         * */
        @Override
        public boolean deleteSurroundingText(int beforeLength, int afterLength) {
            // 做你想做的是拦截他
            Log.i(TAG, "deleteSurroundingText: ----"+beforeLength+"----"+afterLength);
            if (beforeLength == 1 && afterLength == 0) {
                return sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,
                        KeyEvent.KEYCODE_DEL))
                        && sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP,
                        KeyEvent.KEYCODE_DEL));
            }


            return super.deleteSurroundingText(beforeLength, afterLength);
        }
    }
}