我需要做一件非常简单的事情-找出软件键盘是否显示。这在Android中可行吗?


当前回答

医生说… https://developer.android.com/reference/androidx/core/view/WindowInsetsCompat

检查放行说明.. https://developer.android.com/jetpack/androidx/releases/core#1.5.0-alpha02

要获得当前键盘可见性,可以使用getRootWindowInsets,然后调用isVisible()函数,传入IME类型。

val windowinsetscompat = ViewCompat.getRootWindowInsets(view)
val imeVisible = windowinsetscompat.isVisible(Type.ime())

也有监听OnApplyWindowInsetsListener的变化

ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
    val imeVisible = insets.isVisible(Type.ime())
}

其他回答

有一种直接的方法可以找出答案。而且,它不需要任何布局更改。 所以,它也可以在沉浸式全屏模式下工作。 诀窍在于,您尝试隐藏或显示软键盘,并捕获尝试的结果。 没有恐慌,这并不真正显示或隐藏键盘。我们只要求状态。 为了保持最新,您可以简单地重复操作,例如,每200毫秒,使用处理器。 您可以在这里找到一个实现:https://stackoverflow.com/a/27567074/2525452

哇,安卓极客们有好消息了。是时候向旧的方式说再见了。 首先我将添加官方发布说明来阅读和了解更多关于这些方法/类,然后我们将看到这些神奇的方法/类

注意:在这些类/方法发布之前,不要将它们添加到你的发布应用中

如何检查键盘可见性

val insets = ViewCompat.getRootWindowInsets(view)
val isKeyboardVisible = insets.isVisible(Type.ime())

其他用途很少

如何获取键盘的高度

val insets = ViewCompat.getRootWindowInsets(view)
val keyboardHeight = insets.getInsets(Type.ime()).bottom

如何显示/隐藏键盘

val controller = view.windowInsetsController

// Show the keyboard
controller.show(Type.ime())

// Hide the keyboard
controller.hide(Type.ime())

注意:WindowInsetsController是在API-30中添加的,所以要等到向后兼容类不可用。

如何听键盘隐藏/显示事件

ViewCompat.setOnApplyWindowInsetsListener(view) { v, insets ->
    val isKeyboardVisible = insets.isVisible(Type.ime())
    if (isKeyboardVisible) {
        // Do it when keyboard is being shown
    } else {
        // Do it when keyboard is hidden
    }

    // Return the insets to keep going down this event to the view hierarchy
    insets
}

我知道如何准确地确定键盘是否隐藏。

public int getStatusBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public int getNavigationBarHeight() {
    int result = 0;
    int resourceId = getResources().getIdentifier("navigation_bar_height", "dimen", "android");
    if (resourceId > 0) {
        result = getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

public boolean isKeyboardHidden() {
    int delta = mRootView.getRootView().getHeight() - mRootView.getHeight() - getNavigationBarHeight() - getStatusBarHeight()
            - getSupportActionBar().getHeight();
    return delta <= 0;
}

这适用于平板电脑。当导航栏水平显示时。

这里99%的解决方案是基于IME窗口大小的概率,每个这样的解决方案都是一个sh…价值!

因为:

覆盖-来自用户应用程序或系统应用程序 IME没有最小尺寸,它可以占用100%的窗口大小,并且可以像开发人员实现的想象那样薄:) 模态窗口/多窗口 更多的人不了解IPC(例如:外部窗口或其内容检测)

所以猜它是输入法总是错误的-不要猜,一定要确定!!

@kevin-du是目前最好的解决方案,因为它的查询IMM的IME高度-但它说的方法是隐藏的API,所以使用它可能是危险的方式得到错误的“假阴性结果”-通过错误的开发使用。

我花了一点时间才想明白……我运行它一些castexception,但发现你可以用类的名称替换layout.xml中的LinearLayout。

是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent"
    xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/llMaster">

<com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard android:background="@drawable/metal_background"
    android:layout_width="fill_parent" android:layout_height="fill_parent"
    android:id="@+id/rlMaster" >
    <LinearLayout android:layout_width="fill_parent"
        android:layout_height="1dip" android:background="@drawable/line"></LinearLayout>

          ....

</com.ourshoppingnote.RelativeLayoutThatDetectsSoftKeyboard>    


</LinearLayout>

这样你就不会遇到任何演员问题。

... 如果你不想在每个页面上都这样做,我建议你使用“安卓版MasterPage”。点击这里查看链接: http://jnastase.alner.net/archive/2011/01/08/ldquomaster-pagesrdquo-in-android.aspx