Android: Detect softkeyboard open

后端 未结 8 2085
栀梦
栀梦 2020-11-29 07:31

When the soft keyboard opens I want a scroll view to scroll down to the bottom.

For this I can use: fullScroll(View.FOCUS_DOWN);

But how do I fire that comma

相关标签:
8条回答
  • 2020-11-29 07:41

    @BoD's answer works fine if I remove the following line.

    if (mPreviousHeight != 0) {
         /* other code is same, because
            mPreviousHeight is 0 when it comes first */
    }
    
    0 讨论(0)
  • 2020-11-29 07:43

    Here is my solution:

    1/ A simple interface

    public interface KeyboardVisibilityListener {
        void onKeyboardVisibilityChanged(boolean keyboardVisible);
    }
    

    2/ A utility method (put it where you want, for instance in a class named KeyboardUtil)

    public static void setKeyboardVisibilityListener(Activity activity, KeyboardVisibilityListener keyboardVisibilityListener) {
        View contentView = activity.findViewById(android.R.id.content);
        contentView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            private int mPreviousHeight;
    
            @Override
            public void onGlobalLayout() {
                int newHeight = contentView.getHeight();
                if (mPreviousHeight != 0) {
                    if (mPreviousHeight > newHeight) {
                        // Height decreased: keyboard was shown
                        keyboardVisibilityListener.onKeyboardVisibilityChanged(true);
                    } else if (mPreviousHeight < newHeight) {
                        // Height increased: keyboard was hidden
                        keyboardVisibilityListener.onKeyboardVisibilityChanged(false);
                    } else {
                        // No change
                    }
                }
                mPreviousHeight = newHeight;
            }
        });
    }
    

    3/ Use from an Activity this way (a good place is in onCreate):

    KeyboardUtil.setKeyboardVisibilityListener(this, mKeyboardVisibilityListener);
    
    0 讨论(0)
  • 2020-11-29 07:46

    Here is my solution. It doesn't need android:windowSoftInputMode="adjustResize"

    public abstract class KeyboardActivity extends Activity {
        public static final int MIN_KEYBOARD_SIZE = 100;
        private Window mRootWindow;
        private View mRootView;
        private int mKeyboardHeight = -1;
        private ViewTreeObserver.OnGlobalLayoutListener mGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
    
        public int height;
        public void onGlobalLayout() {
                Rect r = new Rect();
            View view = mRootWindow.getDecorView();
            view.getWindowVisibleDisplayFrame(r);
            if (height != r.height()) {
                int diff = height - r.height();
                height = r.height();
                if (Math.abs(diff) > MIN_KEYBOARD_SIZE) {
                    int diff = height - r.height();
                    if (height != 0 && Math.abs(diff) > MIN_KEYBOARD_SIZE) {
                        mKeyboardHeight = Math.abs(diff);
                        if (diff > 0) {
                            onKeyboardOpen();
                        } else {
                            onKeyboardClosed();
                        }
                    }
                    height = r.height();
                }
            }
        };
    
        protected abstract void onKeyboardClosed();
    
        protected abstract void onKeyboardOpen();
    
        /**
         * Should return keyboard height, if keyboard was shown at least once;
         * @return keyboard height or -1
         */
        protected int getKeyboardHeight() {
            return mKeyboardHeight;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mRootWindow = getWindow();
            mRootView = mRootWindow.getDecorView().findViewById(android.R.id.content);
        }
    
        @Override
        protected void onStart() {
            super.onStart();
            mRootView.getViewTreeObserver().addOnGlobalLayoutListener(mGlobalLayoutListener);
        }
    
        @Override
        protected void onStop() {
            super.onStop();
            mRootView.getViewTreeObserver().removeOnGlobalLayoutListener(mGlobalLayoutListener);
        }
    }
    

    Then I've just extend my activity from this activity and override onKeyboardClosed/onKeyboardOpen methods.

    0 讨论(0)
  • 2020-11-29 07:48

    Per this post and this post on android-developers it doesn't seem like it's possible to do what you want. You may want to re-examine your use case for what you're doing. Maybe one of the softInputMode flags will work for you.

    0 讨论(0)
  • 2020-11-29 07:48

    The only way I was able to work around this is by setting my activity's android:windowSoftInputMode="adjustResize" and then embed a custom "detector view" in the layout to handle a container size change and propagate that as a custom event (via a Listener) for soft keyboard on/off.

    The following post describes an approach to implementing it: EditText does not trigger changes when back is pressed

    0 讨论(0)
  • 2020-11-29 07:50

    This works for me

    parent.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
            @Override
            public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
    
                boolean someHasFocus = false;
    
                if(host.hasFocus())
                    someHasFocus = true;
                if(folder.hasFocus())
                    someHasFocus = true;
                if(user.hasFocus())
                    someHasFocus = true;
                if(pass.hasFocus())
                    someHasFocus = true;
    
                if(someHasFocus){
                    if(bottom>oldBottom){
                        // Keyboard Close
                        viewToHide.setVisibility(View.VISIBLE);
    
                    }else if(bottom<oldBottom){
                       // Keyboard Open
                        viewToHide.setVisibility(View.GONE);
                    }
    
                }else{
                    // show
                    viewToHide.setVisibility(View.VISIBLE);
                }
            }
        });
    

    Where parent is the main layout, viewToHide is the view that shows or hides when the keyboard is shown, and host,folder,user and pass are the EditText of my form.

    And this in the manifest

    android:windowSoftInputMode="stateHidden|adjustResize"
    

    Hope this help

    0 讨论(0)
提交回复
热议问题