Android系统中是否有一种方法可以检测软件(也就是Android。“软”)键盘在屏幕上可见吗?


当前回答

如你所知,android软件的键盘只有在有可能的输入事件时才可见。换句话说,只有当EditText被聚焦时,键盘才可见。这意味着你可以通过使用OnFocusChangeListener获得键盘是否可见。

//Declare this Globally

public boolean isKeyBoardVisible = false;

//In OnCreate *[For Activity]*, OnCreateView *[For Fragment]*

text_send.setOnFocusChangeListener(new View.OnFocusChangeListener() {

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if(hasFocus)
            isKeyBoardVisible = true;
        else
            isKeyBoardVisible = false;
    }
});

现在你可以在类的任何地方使用isKeyBoardVisible变量来获取键盘是否打开。这对我来说很有效。

注意:当使用InputMethodManager以编程方式打开键盘时,这个过程不起作用,因为它不调用OnFocusChangeListener。

其他回答

在我的情况下,我只有一个编辑文本来管理我的布局,所以我想出了这个解决方案。 它工作得很好,基本上它是一个自定义的EditText,它监听焦点,并在焦点改变或按下后退/完成按钮时发送本地广播。 要工作,你需要在你的布局与android: focableintouchmode ="true"和android:focusableInTouchMode="true",因为当你调用clearFocus()的焦点将被重新分配到第一个可聚焦的视图。 虚拟视图示例:

<View
android:layout_width="1dp"
android:layout_height="1dp"
android:focusable="true"
android:focusableInTouchMode="true"/>

额外的信息

检测布局变化差异的解决方案效果不太好,因为它强烈依赖于屏幕密度,因为100px在某些设备上可能很大,而在其他设备上可能没有,你可能会得到误报。 另外,不同的厂商有不同的键盘。

如果你的应用程序支持AndroidR的api,那么你可以使用下面的方法。

In kotlin :
    var imeInsets = view.rootWindowInsets.getInsets(Type.ime()) 
    if (imeInsets.isVisible) { 
        view.translationX = imeInsets.bottom 
    }

注意:这只适用于AndroidR和以下的android版本需要遵循一些其他的答案,否则我会更新它。

A可能会使用:

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    Log.d(
    getClass().getSimpleName(), 
    String.format("conf: %s", newConfig));

    if (newConfig.hardKeyboardHidden != hardKeyboardHidden) {
        onHardwareKeyboardChange(newConfig.hardKeyboardHidden);

        hardKeyboardHidden = newConfig.hardKeyboardHidden;
    }

    if (newConfig.keyboardHidden != keyboardHidden) {
        onKeyboardChange(newConfig.keyboardHidden);

        keyboardHidden = newConfig.hardKeyboardHidden;
    }

}

public static final int KEYBOARDHIDDEN_UNDEFINED = 0;
public static final int KEYBOARDHIDDEN_NO = 1;
public static final int KEYBOARDHIDDEN_YES = 2;
public static final int KEYBOARDHIDDEN_SOFT = 3;

//todo
private void onKeyboardChange(int keyboardHidden) {

}

//todo
private void onHardwareKeyboardChange(int hardKeyboardHidden) {

}

试试这个,对我很有效

InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if (imm.isActive())
        //Keyboard is active

我把答案转换为kotlin,希望这对kotlin用户有帮助。

private fun checkKeyboardVisibility() {
    var isKeyboardShowing = false

    binding.coordinator.viewTreeObserver.addOnGlobalLayoutListener {
        val r = Rect()
        binding.coordinator.getWindowVisibleDisplayFrame(r)
        val screenHeight = binding.coordinator.rootView.height

        // r.bottom is the position above soft keypad or device button.
        // if keypad is shown, the r.bottom is smaller than that before.
        val keypadHeight = screenHeight - r.bottom


        if (keypadHeight > screenHeight * 0.15) { // 0.15 ratio is perhaps enough to determine keypad height.
            // keyboard is opened
            if (!isKeyboardShowing) {
                isKeyboardShowing = true

            }
        } else {
            // keyboard is closed
            if (isKeyboardShowing) {
                isKeyboardShowing = false

            }
        }
    }
}