Soft keyboard open and close listener in an activi

2019-01-01 12:37发布

I have an Activity where there are 5 EditTexts. When the user clicks on the first EditText, the soft keyboard opens to enter some value in it. I want to set some other View's visibility to Gone when the soft keyboard opens and also when the user clicks on the first EditText and also when the soft keyboard closes from the same EditText on the back button press. Then I want to set some other View's visibility to visible.

Is there any listener or callback or any hack for when the soft keyboard opens from a click on the first EditText in Android?

20条回答
骚的不知所云
2楼-- · 2019-01-01 13:33

If you can, try to extend EditText and override 'onKeyPreIme' method.

@Override
public void setOnEditorActionListener(final OnEditorActionListener listener) {
    mEditorListener = listener; //keep it for later usage
    super.setOnEditorActionListener(listener);
}

@Override
public boolean onKeyPreIme(final int keyCode, final KeyEvent event) {
    if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
        if (mEditorListener != null) {
            //you can define and use custom listener,
            //OR define custom R.id.<imeId>
            //OR check event.keyCode in listener impl
            //* I used editor action because of ButterKnife @
            mEditorListener.onEditorAction(this, android.R.id.closeButton, event);
        }
    }
    return super.onKeyPreIme(keyCode, event);
}

How can you extend it:

  1. Implement onFocus listening and declare 'onKeyboardShown'
  2. declare 'onKeyboardHidden'

I think, that recalculating of screen height is not 100% successfully as mentioned before. To be clear, overriding of 'onKeyPreIme' is not called on 'hide soft keyboard programatically' methods, BUT if you are doing it anywhere, you should do 'onKeyboardHidden' logic there and do not create a comprehensive solutions.

查看更多
大哥的爱人
3楼-- · 2019-01-01 13:34
private boolean isKeyboardShown = false;
private int prevContentHeight = 0;
private ViewGroup contentLayout;

private ViewTreeObserver.OnGlobalLayoutListener keyboardLayoutListener =
        new ViewTreeObserver.OnGlobalLayoutListener() {

    @Override
    public void onGlobalLayout() {
        int contentHeight = contentLayout.getHeight();
        int rootViewHeight = contentLayout.getRootView().getHeight();

        if (contentHeight > 0) {

            if (!isKeyboardShown) {
                if (contentHeight < prevContentHeight) {
                    isKeyboardShown = true;
                    onShowKeyboard(rootViewHeight - contentHeight);
                }
            } else {
                if (contentHeight > prevContentHeight) {
                    isKeyboardShown = false;
                    onHideKeyboard();
                }
            }

            prevContentHeight = contentHeight;
        }
    }
};

I've modified the Jaap's accepted answer a bit. But in my case, there are few assumptions such as android:windowSoftInputMode=adjustResize and the keyboard does not show up at the beginning when the app starts. And also, I assume that the screen in regard matches the parent's height.

contentHeight > 0 this check provides me to know if the regarding screen is hidden or shown to apply keyboard event listening for this specific screen. Also I pass the layout view of the regarding screen in attachKeyboardListeners(<your layout view here>) in my main activity's onCreate() method. Every time when the height of the regarding screen changes, I save it to prevContentHeight variable to check later whether the keyboard is shown or hidden.

For me, so far it's been worked pretty well. I hope that it works for others too.

查看更多
登录 后发表回答