關(guān)于Android中軟鍵盤顯示隱藏的監(jiān)聽判斷總結(jié)

前言

很多時(shí)候我們需要知道軟鍵盤是否打開和關(guān)閉,從而處理一些需求。之前在做shou app的時(shí)候,由于交互比較復(fù)雜,需要知道軟鍵盤是開啟或者關(guān)閉,決定是否讓視頻全屏,還是讓聊天室全屏,或者是正常顯示(上面是視頻,下面是聊天室)

ViewTreeObserver.OnGlobalLayoutListener

OnGlobalLayoutListener 是ViewTreeObserver的內(nèi)部類,當(dāng)一個(gè)視圖樹的布局發(fā)生改變時(shí),可以被ViewTreeObserver監(jiān)聽到,這是一個(gè)注冊(cè)監(jiān)聽視圖樹的觀察者(observer),在視圖樹的全局事件改變時(shí)得到通知。ViewTreeObserver不能直接實(shí)例化,而是通過(guò)getViewTreeObserver()獲得。
以上是說(shuō)明,摘抄自http://www.cnblogs.com/superle/p/4567400.html這篇文章,也就是說(shuō),通過(guò)這個(gè)api,我們可以知道view的布局狀態(tài)變化

如何監(jiān)聽軟鍵盤

KeyboardChangeListener github上有這樣的一個(gè)輪子,測(cè)試了下,的確有效,思路是,對(duì)android.R.id.content所對(duì)應(yīng)的view設(shè)置監(jiān)聽,監(jiān)聽它的高度變化,計(jì)算比較,來(lái)確定軟件盤是否彈起或者收攏了。這種模式需要設(shè)置activity
android:windowSoftInputMode="adjustResize"

full screen模式下如何監(jiān)聽軟件盤

在full screen 狀態(tài)上,發(fā)現(xiàn),以上的方案完全不起作用了。在https://pspdfkit.com/blog/2016/keyboard-handling-on-android/ 上找到了解決辦法。
大致上說(shuō)的是full screen模式下,adjustResize不會(huì)生效了,window不會(huì)resize的。
getWindowVisibleDisplayFrame(Rect)這個(gè)api可以獲取到view所在的區(qū)域,通過(guò)它比較每次區(qū)域的變化,可以實(shí)現(xiàn)監(jiān)聽軟鍵盤是否可見
完整代碼為:


public class KeyBoardChangeListener implements ViewTreeObserver.OnGlobalLayoutListener {
    private static final String TAG = "KeyBoardChangeListener";
    // Threshold for minimal keyboard height.
    final int MIN_KEYBOARD_HEIGHT_PX = 150;
    private final Rect windowVisibleDisplayFrame = new Rect();
    // Top-level window decor view.
    private View decorView;
    private int lastVisibleDecorViewHeight;
    private KeyBoardListener keyBoardListener;

    KeyBoardChangeListener(Activity activity) {
        if (activity == null) {
            Log.e(TAG, "activity is null");
            return;
        }
        decorView = activity.getWindow().getDecorView();
        decorView.getViewTreeObserver().addOnGlobalLayoutListener(this);
    }

    public void setKeyBoardListener(KeyBoardListener keyBoardListener) {
        this.keyBoardListener = keyBoardListener;
    }

    @Override
    public void onGlobalLayout() {
        // Retrieve visible rectangle inside window.
        decorView.getWindowVisibleDisplayFrame(windowVisibleDisplayFrame);
        final int visibleDecorViewHeight = windowVisibleDisplayFrame.height();
        // Decide whether keyboard is visible from changing decor view height.
        if (lastVisibleDecorViewHeight != 0) {
            if (lastVisibleDecorViewHeight > visibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX) {
                // Calculate current keyboard height (this includes also navigation bar height when in fullscreen mode).
                int currentKeyboardHeight = decorView.getHeight() - windowVisibleDisplayFrame.bottom;
                // Notify listener about keyboard being shown.
                if (keyBoardListener != null) {
                    keyBoardListener.onKeyboardChange(true, currentKeyboardHeight);
                }
            } else if (lastVisibleDecorViewHeight + MIN_KEYBOARD_HEIGHT_PX < visibleDecorViewHeight) {
                // Notify listener about keyboard being hidden.
                if (keyBoardListener != null) {
                    keyBoardListener.onKeyboardChange(false, 0);
                }
            }
        }
        // Save current decor view height for the next call.
        lastVisibleDecorViewHeight = visibleDecorViewHeight;
    }

    public interface KeyBoardListener {
        /**
         * call back
         *
         * @param isShow         true is show else hidden
         * @param keyboardHeight keyboard height
         */
        void onKeyboardChange(boolean isShow, int keyboardHeight);
    }
}

相關(guān)參考

https://pspdfkit.com/blog/2016/keyboard-handling-on-android/
KeyboardChangeListener
https://gist.github.com/xingstarx/7a535fdda432e7678b53c628099c96ab

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容