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


当前回答

Reuben Scratton和Kachi提供的解决方案似乎依赖于设备的像素密度,如果你有一个高密度的设备,即使按下键盘,高度差也可能超过100。围绕这一点的工作将是看到初始高度差(键盘向下),然后与当前的差异进行比较。

boolean isOpened = false;
int firstHeightDiff = -1;

public void setListenerToRootView(){
    final View activityRootView = getActivity().getWindow().getDecorView().findViewById(android.R.id.content);
    Rect r = new Rect();
    activityRootView.getWindowVisibleDisplayFrame(r);
    firstHeightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
    activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (isAdded()) {
                Rect r = new Rect();
                activityRootView.getWindowVisibleDisplayFrame(r);
                int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
                isOpened = heightDiff>firstHeightDiff+100;
                if (isAdded())
                    if(isOpened) {
                        //TODO stuff for when it is up
                    } else {
                        //TODO stuf for when it is down
                    }
            }
        }
    });
}

其他回答

希望这能帮助到大家。

Reuben Scratton给出的新答案非常棒,而且非常有效,但它只在你将windowSoftInputMode设置为adjuststresize时才有效。如果你将它设置为adjustPan,使用他的代码片段仍然无法检测键盘是否可见。为了解决这个问题,我对上面的代码做了微小的修改。

final View activityRootView = findViewById(R.id.activityRoot);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
    Rect r = new Rect();
    //r will be populated with the coordinates of your view that area still visible.
    activityRootView.getWindowVisibleDisplayFrame(r);
   
    int heightDiff = activityRootView.getRootView().getHeight() - r.height();
    if (heightDiff > 0.25*activityRootView.getRootView().getHeight()) { // if more than 25% of the screen, its probably a keyboard...
        ... do something here
    }
 }
}); 

这里有一个工作区,以了解软键盘是否可见。

检查系统上正在运行的服务 ActivityManager.getRunningServices (max_count_of_services); 从返回的ActivityManager。运行ningserviceinfo实例,检查软键盘服务的clientCount值。 前面提到的clientCount将在每次显示软键盘时递增。例如,如果clientCount为 一开始是1,显示键盘时是2。 在键盘撤销时,clientCount递减。在本例中,它重置为1。

一些流行的键盘在它们的classname中有特定的关键字:

Google AOSP = IME
Swype = IME
Swiftkey = KeyboardService
Fleksy = keyboard
Adaptxt = IME (KPTAdaptxtIME)
Smart = Keyboard (SmartKeyboard)

从ActivityManager。RunningServiceInfo,在ClassNames中检查上述模式。同时,ActivityManager。RunningServiceInfo的clientPackage=android,表示键盘绑定到系统。

可以将上述信息进行严格的组合,以判断软键盘是否可见。

检查元素的高度是不可靠的,因为一些键盘,如WifiKeyboard的高度为零。

相反,您可以使用showSoftInput()和hideSoftInput()的回调结果来检查键盘的状态。完整的细节和示例代码在

https://rogerkeays.com/how-to-check-if-the-software-keyboard-is-shown-in-android

我认为这个方法将帮助你找出是键盘是可见的或不。

 public Boolean isSoftKeyBoardVisible(){
    InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);

    if (imm.isAcceptingText()) {
        Log.d(TAG,"Software Keyboard was shown");
        return true;
    } else {
        Log.d(TAG,"Software Keyboard was not shown");
        return false;
    }

}

这是我的解决方案,它很有效。而不是寻找像素大小,只是检查内容视图的高度是否改变:

// Scroll to the latest comment whenever the keyboard is shown
commentsContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {

        private int oldHeight;

        @Override
        public void onGlobalLayout() {
            int newHeight = commentsContent.getMeasuredHeight();
            if (newHeight < oldHeight) {
                // Check for the keyboard showing in case the height difference
                // is a result of orientation change
                if (isSoftKeyboardShowing(CommentsActivity.this)) {
                    // Keyboard is showing so scroll to the latest comment
                    scrollToLatestComment();
                }
            }
            oldHeight = newHeight;
        }

    });


public static boolean isSoftKeyboardShowing(Activity activity) {
    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    return inputMethodManager.isActive();
}