學(xué)習(xí)windowSoftInputMode,解決軟鍵盤遮擋住輸入框的問題

今天在項(xiàng)目中遇到了一個(gè)軟鍵盤遮擋住輸入框的特殊案例,經(jīng)過和搭檔的研究,終于完美解決了。寫下這篇文章,記錄一下,順便回顧學(xué)習(xí)windowSoftInputMode系列屬性以及軟鍵盤的相關(guān)知識(shí)。


windowSoftInputMode

下面是windowSoftInputMode的Documentation

Formats: flag

Values: adjustNothing, adjustPan, adjustResize, adjustUnspecified, stateAlwaysHidden, stateAlwaysVisible, stateHidden, stateUnchanged, stateUnspecified, stateVisible

Specify the default soft-input mode for the main window of this activity. A value besides "unspecified" here overrides any value in the theme.

我的英語知識(shí)小學(xué)級(jí)別的,哈哈……上面的大概意思呢,我認(rèn)為就是說:這是一個(gè)標(biāo)簽,它可以取的值有這么多,我們可以從中選擇設(shè)置一個(gè)值來控制當(dāng)前這個(gè)活動(dòng)窗口與軟鍵盤之間的交互。既然是交互,這時(shí)就有兩種狀態(tài),從這些values的命名也可以看出來,一種是窗口的,一種是軟鍵盤的

  • window: adjustNothing, adjustPan, adjustResize, adjustUnspecified

  • softInput:stateAlwaysHidden, stateAlwaysVisible, stateHidden, stateUnchanged, stateUnspecified, stateVisible

它的設(shè)置必須是下面列表中的一個(gè)值,或一個(gè) ”state…”值加一個(gè) ”adjust…”值的組合。

作用
adjustPan 當(dāng)顯示軟鍵盤時(shí),調(diào)整window的空白區(qū)域來顯示軟鍵盤。軟鍵盤還是有可能遮擋一些有內(nèi)容區(qū)域,這時(shí)用戶就只有退出軟鍵盤才能看到這些被遮擋區(qū)域并進(jìn)行交互。
adjustNothing 當(dāng)顯示軟鍵盤時(shí),不調(diào)整window的布局
adjustResize 當(dāng)顯示軟鍵盤時(shí),調(diào)整window內(nèi)的控件大小以便顯示軟鍵盤。這樣的話控件可能會(huì)變形。
adjustUnspecified 不指定顯示軟件盤時(shí),window的調(diào)整方式。系統(tǒng)去判斷內(nèi)容區(qū)域可滾動(dòng)為adjustPan,不可滾動(dòng)為adjustResize
stateAlwaysHidden 總是隱藏軟鍵盤。
stateAlwaysVisible 總是顯示軟鍵盤
stateHidden 用戶導(dǎo)航(navigate)到你的窗口的時(shí)候,隱藏軟鍵盤
stateVisible 用戶導(dǎo)航(navigate)到你的窗口的時(shí)候,顯示軟鍵盤
stateUnchanged 當(dāng)這個(gè)activity出現(xiàn)時(shí),軟鍵盤將一直保持在上一個(gè)activity里的狀態(tài),無論是隱藏還是顯示
stateUnspecified 未指定軟鍵盤的狀態(tài),系統(tǒng)將自動(dòng)選擇一個(gè)合適的狀態(tài)或依賴于主題中的設(shè)置,這是默認(rèn)的設(shè)置

軟鍵盤顯示和隱藏
正好前兩天用到代碼去設(shè)置軟鍵盤的彈出與隱藏,也在此記錄一下,因?yàn)轱@示與隱藏軟件盤的方式都有多種,但是有的卻是不起作用,下面是兩種親測可用的顯示與隱藏方法

  /**
     * 隱藏軟鍵盤
     * @param view
     */
    public static void hideSoftKeyboard() {
        if (view == null || BaseApplication.getContext() == null)
            return;

        ((InputMethodManager) BaseApplication.getContext().getSystemService(
                Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
                view.getWindowToken(), 0);
    }
    /**
     * 顯示軟鍵盤
     */
    public static void showSoftKeyboard(){
        ((InputMethodManager) BaseApplication.getContext().getSystemService(
                Context.INPUT_METHOD_SERVICE)).toggleSoftInput(0, InputMethodManager.RESULT_SHOWN);

    }

以上,將知識(shí)順了一遍;下面,來說說我今天是怎么爬坑的


無標(biāo)題.png

我的布局如圖所示,在AndroidManifest中進(jìn)行設(shè)置該Activity:

  1. windowSoftInputMode="adjustNothing"
    這時(shí),當(dāng)軟件盤彈出時(shí),window不作調(diào)整,當(dāng)頁面向上滑動(dòng)到頂時(shí),下面有輸入框,會(huì)被軟鍵盤蓋住
  2. windowSoftInputMode="adjustPan"
    這時(shí),當(dāng)軟鍵盤彈出時(shí),window調(diào)整頁面顯示,這個(gè)是調(diào)整空白區(qū)域,會(huì)自動(dòng)將獲取焦點(diǎn)的輸入框滑動(dòng)到彈出的軟鍵盤上方,但是,當(dāng)最下方的輸入框,還是會(huì)被遮擋,這時(shí)window已經(jīng)調(diào)整不了,并且頁面向上滑動(dòng)時(shí),Toolbar也會(huì)被頂出屏幕
  3. windowSoftInputMode="adjustResize"
    • 這時(shí),當(dāng)軟鍵盤彈出時(shí),window調(diào)整頁面顯示,這個(gè)調(diào)整是調(diào)整整個(gè)頁面的大小,比如,現(xiàn)在軟鍵盤彈出,那么上面我這個(gè)頁面,等于是整體往上壓縮,下面擠出一個(gè)可以放下軟鍵盤的區(qū)域,所以,就會(huì)把我下方的LinearLayout區(qū)域都擠上去,那么整個(gè)頁面都變形了。
  • 想辦法:監(jiān)聽Scrollview的布局是否改變,判斷它的bottom變大變小,將LinearLayout顯示隱藏,想法是好的,但是,軟鍵盤彈出,LinearLayout隱藏后,軟鍵盤上方總是有一塊和我布局下方LinearLayout同樣大小的灰色區(qū)域,并且,當(dāng)退出軟鍵盤后,如果用的隱藏是VIEW.GONE的話,LinearLayout就回不來了
  • 查找后,發(fā)現(xiàn)灰色區(qū)域原因出在我的Scrollview的布局屬性weight=1上;至于設(shè)置成VIEW.GONE下方的LinearLayout再設(shè)置成VIEW.VISIBLE也回不來,不再顯示,不明白,只能先用VIEW.VISIBLE屬性
  1. 解決辦法:
  • windowSoftInputMode="adjustResize"
  • 根布局修改為RelativeLayout,不再用weight屬性,解決了軟鍵盤上方灰色區(qū)域問題
//添加布局改變監(jiān)聽
        scrollviewActorder.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) {
                LogUtil.ShowLog(bottom+"==="+oldBottom);

                if (oldBottom>bottom) {
                    // 打開了軟鍵盤,觸發(fā)了界面resize
                    // 隱藏下方價(jià)格,按鈕
                    LogUtil.ShowLog("size change ----------");
                    llBottom.setVisibility(View.INVISIBLE);
                    llBottom.setFocusable(false);
                }else if(bottom>oldBottom){
                    llBottom.setVisibility(View.VISIBLE);
                    llBottom.setFocusable(true);
                }
            }
        });

經(jīng)過上面一系列的折騰,終于,將軟鍵盤遮擋住輸入框的問題完美解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容