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


当前回答

视图#setOnApplyWindowInsetsListener可以用来获得窗口insets回调

public void setOnApplyWindowInsetsListener(OnApplyWindowInsetsListener listener) {
    getListenerInfo().mOnApplyWindowInsetsListener = listener;
}

//OnApplyWindowInsetsListener
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets);

boolean keyboardVisible = insets.isVisible(WindowInsets.Type.ime())可以给出可见性状态。

其他回答

这个解决方案可能会重新打开键盘,但它是有效的。

InputMethodManager inputManager = ( (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE) );

private boolean isKeyboardShowing() {

    boolean isKeyboardShowing = inputManager.hideSoftInputFromWindow(irrelevantView.getWindowToken(), 0);
    if (isKeyboardShowing) {
        inputManager.showSoftInput(this.getCurrentFocus(), 0);
    }
    return isKeyboardShowing;
}

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

因为:

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

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

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

这个想法是,如果你需要隐藏你的键盘,同时检查软输入状态,使用以下解决方案:

public boolean hideSoftInput() {
    InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
    return imm.hideSoftInputFromWindow(mViewPager.getWindowToken(), 0);
}

如果在隐藏之前显示键盘,则此方法返回true。

而不是假设差异编码,我做了这样的事情,因为我在我的应用程序中有菜单选项。

final View root= findViewById(R.id.myrootview); 
root.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
    public void onGlobalLayout() {
        int heightDiff = root.getRootView().getHeight() - root.getHeight();

        Rect rectgle= new Rect();
        Window window= getWindow();
        window.getDecorView().getWindowVisibleDisplayFrame(rectgle);
        int contentViewTop=                     
          window.findViewById(Window.ID_ANDROID_CONTENT).getTop();
        if(heightDiff <= contentViewTop){
            //Soft KeyBoard Hidden
        }else{
            //Soft KeyBoard Shown
        }
     }
});

在使用上述大多数建议添加固定数字的解决方案时,我刚刚遇到了一个错误。

S4的dpi很高,导致导航栏的高度为100px,因此我的应用程序认为键盘一直是打开的。

所以,随着所有新的高分辨率手机的发布,我认为使用硬编码值从长远来看不是一个好主意。

在各种屏幕和设备上进行测试后,我发现一个更好的方法是使用百分比。 获取decorView和你的应用内容之间的差异,然后检查这个差异的百分比。 从我得到的统计数据来看,大多数导航栏(无论大小、分辨率等)将占据屏幕的3%到5%。如果键盘是打开的,它会占据屏幕的47%到55%。

作为结论,我的解决方案是检查是否差异超过10%,然后我假设它的键盘打开。