You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Cordova实现不丢失输入框焦点隐藏软键盘的方法

解决安卓输入框获焦时隐藏软键盘且保留焦点的方案

我太懂你这个场景的痛点了——扫码枪作为核心输入设备,软键盘弹出来不仅干扰操作,还容易抢输入焦点,关键还得让输入框保持激活状态才能接收扫码枪的模拟键盘输入。之前我做类似的扫码应用时踩过不少坑,给你分享几个亲测有效的实现思路:

方法一:自定义EditText(最可靠的方案)

直接从输入连接的源头切断软键盘的触发,同时保留输入框的焦点和光标,完全适配扫码枪输入:

public class ScannerEditText extends androidx.appcompat.widget.AppCompatEditText {
    public ScannerEditText(Context context) {
        super(context);
        initView();
    }

    public ScannerEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public ScannerEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    private void initView() {
        // 保持光标可见,让用户明确知道输入框处于激活状态
        setCursorVisible(true);
        // 处理点击事件:点击时请求焦点,但不触发软键盘
        setOnTouchListener((v, event) -> {
            requestFocus();
            hideSoftKeyboard();
            return true;
        });
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
        // 返回null,阻止系统创建输入连接,从根源上避免软键盘弹出
        return null;
    }

    private void hideSoftKeyboard() {
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.hideSoftInputFromWindow(getWindowToken(), 0);
        }
    }
}

之后在布局里直接用这个自定义控件代替普通EditText就行,扫码枪的输入完全不受影响——因为扫码枪是模拟硬件键盘输入,只要输入框有焦点就能正常接收内容。

方法二:给普通EditText添加焦点监听(无需自定义控件)

如果不想改布局用自定义控件,也可以通过监听焦点变化来动态控制软键盘:

// 在Activity/Fragment中初始化EditText时设置监听
EditText yourEditText = findViewById(R.id.your_edit_text);
yourEditText.setOnFocusChangeListener((v, hasFocus) -> {
    if (hasFocus) {
        // 禁用系统软键盘的输入类型
        yourEditText.setInputType(InputType.TYPE_NULL);
        // 手动隐藏可能已经弹出的软键盘
        hideSoftKeyboard(yourEditText);
        // 确保光标可见
        yourEditText.setCursorVisible(true);
    } else {
        // 失去焦点时恢复输入类型,方便后续需要手动弹出软键盘的场景
        yourEditText.setInputType(InputType.TYPE_CLASS_TEXT);
    }
});

// 通用的软键盘隐藏方法
private void hideSoftKeyboard(View view) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm != null) {
        imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
    }
}

手动控制软键盘显隐的补充

针对你提到的“特定按钮控制软键盘”的需求,当需要弹出软键盘时,可以用这个方法:

private void showSoftKeyboard(View view) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm != null) {
        // 先恢复输入类型(如果之前设置了TYPE_NULL)
        view.setInputType(InputType.TYPE_CLASS_TEXT);
        view.requestFocus();
        imm.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

为什么之前的插件没生效?

大概率是插件触发隐藏软键盘的时机不对——系统在输入框获焦时会优先触发软键盘弹出,插件如果在这之后才调用隐藏,就会出现“弹出来又缩回去”的闪烁,甚至完全失效。而上面的两种方法要么从源头阻止软键盘触发,要么在焦点变化的第一时间禁用软键盘,可靠性更高。

内容的提问来源于stack exchange,提问作者Mistre83

火山引擎 最新活动