1. 程式人生 > >Android 解決輸入法遮擋佈局控制元件的問題

Android 解決輸入法遮擋佈局控制元件的問題

                文章說明:本文章核心解決方案來自這裡 戳我戳我   ,本文章主要對原方法的小修改,以及使用時遇到的一些問題的解決分享。

   /**
     * 佈局在輸入法之上
     *
     * @param root    最外層佈局,需要調整的佈局
     * @param btmView 最底部的控制元件
     */
    public static ViewTreeObserver.OnGlobalLayoutListener getKeyboardListener(final View root, final View btmView) {
       return new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect rect = new Rect();
                //獲取root在窗體的可視區域
                root.getRootView().getWindowVisibleDisplayFrame(rect);
                //獲取root在窗體的不可視區域高度(被其他View遮擋的區域高度)
                int rootInvisibleHeight = root.getRootView().getHeight() - rect.bottom;
                //若不可視區域高度大於 h/4,則鍵盤顯示
                if (rootInvisibleHeight > root.getRootView().getHeight() / 4) {
                    int[] location;
                    if (btmView.getTag() == null) {
                        location = new int[2];
                        //獲取scrollToView在窗體的座標
                        btmView.getLocationInWindow(location);
                        btmView.setTag(location);
                    } else {
                        location = (int[]) btmView.getTag();
                    }

                    //計算root滾動高度,使scrollToView在可見區域
                    final int srollHeight = (location[1] + btmView.getHeight()) - rect.bottom;
                    if (srollHeight != 0) {
                        root.scrollTo(0, srollHeight);
                            if (root instanceof ScrollView) {
                                root.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        ((ScrollView) root).fullScroll(View.FOCUS_DOWN);
                                    }
                                });
                            }
                    }
                } else {
                    //鍵盤隱藏
                    root.scrollTo(0, 0);
                }
            }
        };
    }

    //移除佈局監聽
    public static void removeGlobalLayoutListener(View root, ViewTreeObserver.OnGlobalLayoutListener listener) {
        if (root != null && listener != null) {
            //最低api 16
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                root.getViewTreeObserver().removeOnGlobalLayoutListener(listener);
            } else {
                root.getViewTreeObserver().removeGlobalOnLayoutListener(listener);
            }
        }
    }
   
    //使用方式 初始化時加入監聽
    ViewTreeObserver.OnGlobalLayoutListener  mKeyboardListener = getKeyboardListener(root, btmView);
    root.getViewTreeObserver().addOnGlobalLayoutListener(mKeyboardListener);
 
    //退出的時候移除監聽
    removeGlobalLayoutListener(root, mKeyboardListener);

        以上核心程式碼和 戳我 裡面的基本一致,但也有點小區別,多了下面的操作:  

    if (root instanceof ScrollView) {
                        root.post(new Runnable() {
                            @Override
                            public void run() {
                                ((ScrollView) root).fullScroll(View.FOCUS_DOWN);
                            }
                        });
                    }

      當rootView 為  scrollview時,有些系統(可能是低版本系統),scrollview內的控制元件並不會一起往上移到,雖然scrollview已經在輸入法上面了

  (被遮擋的控制元件可以通過滑動看到),但整體效果還是遮擋,所以以上的判斷就是解決scrollview內控制元件被遮擋問題。

      以上的方法足以解決大部分Activity的主佈局被輸入法遮擋問題,當你用的是Fragment捆綁在Activity裡面,如果只是簡單呼叫這個監聽方法,

   那就不一定得到你想要的效果了,必須為這個Activity設定輸入法監聽了,這裡提供一個參考,在manifest裡面對應的Activity設定    

   android:windowSoftInputMode 屬性,如:

 <activity
            android:name=".XxxActivity"
            android:windowSoftInputMode="adjustPan" />

                         如果我的文章幫到了你,請。。麻煩。。多謝!