Android - KeyBoard鍵盤(windowSoftInputMode)

近期在項(xiàng)目中遇到了,Android軟鍵盤相關(guān)的內(nèi)容困擾了好久,也在這里記錄一下,方便查閱:

軟鍵盤的顯示調(diào)整(WindowSoftInputMode)

該屬性有如下圖的值,影響兩個(gè)方面:
1,當(dāng)Activity成為用戶注意的焦點(diǎn)時(shí)軟鍵盤的狀態(tài)(隱藏or可見)。
2,軟鍵盤彈出的時(shí)候,主窗口是否進(jìn)行調(diào)整。

windowSoftInputMode.png

以上屬性,分為stateadjust兩種(一般使用的時(shí)候也是stateXXX | adjustXXX混合使用):

state控制軟鍵盤,顯示 or 隱藏

stateUnspecified:不指定軟鍵盤的狀態(tài)(隱藏or顯示),該屬性將由系統(tǒng)自行選擇(也是默認(rèn)的狀態(tài))。
stateUnchanged:保留狀態(tài)。當(dāng)activity發(fā)生變化的時(shí)候,保留軟鍵盤最后的狀態(tài),無論是可見or隱藏。
stateHidden:隱藏軟鍵盤,當(dāng)用戶設(shè)置了該屬性,不管是否界面有輸入需求,鍵盤都不顯示??梢栽O(shè)置該屬性,控制剛進(jìn)入界面的時(shí)候,軟鍵盤不彈出。
stateAlwaysHidden:始終隱藏軟鍵盤。
stateVisible:顯示軟鍵盤,正常的情況下軟鍵盤可以彈出,即使界面沒有輸入框的情況下,也可以強(qiáng)制彈出。
stateAlwaysVisible:總是顯示軟鍵盤。如果當(dāng)前activity設(shè)置為該屬性,那么只要返回到該activity,軟鍵盤就會(huì)彈出。區(qū)別一下stateVisible如果設(shè)置的是這個(gè)屬性切換回activity軟鍵盤不會(huì)總是彈出。

adjust在軟鍵盤彈出的時(shí)候,是否需要對(duì)activity進(jìn)行調(diào)整

adjustUnspecified:默認(rèn)屬性。讓系統(tǒng)自行選擇。
adjustResize:始終調(diào)整activity的窗口尺寸,來為軟鍵盤騰出空間。

adjustPan:不調(diào)整Activity 主窗口的尺寸來為軟鍵盤騰出空間,而是自動(dòng)平移窗口的內(nèi)容,以使焦點(diǎn)不被覆蓋,用戶始終可以看到輸入的內(nèi)容

adjustNothing:軟鍵盤彈出的時(shí)候,activity界面不做任何響應(yīng)。

舉例說明

常用的adjust為:

  • adjustPan:軟鍵盤彈出,主窗口平移(TranslateY),來適應(yīng)軟鍵盤的顯示。
  • adjustResize:當(dāng)軟鍵盤彈出的時(shí)候,會(huì)讓布局重新繪制,這種一般適應(yīng)于帶有滑動(dòng)的控制(比如:scrollview中有好多個(gè)EditText,當(dāng)?shù)谝粋€(gè)獲取焦點(diǎn)的時(shí)候,仍可以滑動(dòng)到最后一個(gè)EditText)。

看了好多博客,都說該屬性設(shè)置的時(shí)候,跟控件是否滑動(dòng)有區(qū)別,自己也寫了個(gè)demo測試了一下,見下面的gif圖:


mode為:adjustResize.gif
  • adjustResize
    可以從上圖看出,當(dāng)mode為adjustResize的時(shí)候,可以滑動(dòng)的列表(上圖左側(cè)),會(huì)調(diào)整布局,使得EditText顯示到軟鍵盤之上,并且可以滑動(dòng)。
    不可滑動(dòng)的界面,如果點(diǎn)擊下方的EditText,軟鍵盤彈出就會(huì)被遮蓋。
adjustPan.gif

-adjustPan
從上圖可以看出,mode為adjuetPan的時(shí)候,可滑動(dòng)列表無法顯示當(dāng)前獲取焦點(diǎn)的EditText以下的內(nèi)容(例如點(diǎn)擊可以滑動(dòng)的EditText_7,無法下拉看到下面的內(nèi)容),也就是用戶始終可以看到輸入的內(nèi)容。
不可滑動(dòng)的EditText,也是如此,會(huì)將布局向上推,以達(dá)到用戶可以始終看到的目的。

監(jiān)聽軟鍵盤是否彈出

在項(xiàng)目中有一個(gè)需求,就是不能讓軟鍵盤覆蓋輸入的內(nèi)容。使用以上windowSoftInputMode
實(shí)現(xiàn)的方式:
1,獲取decorView的高度,跟當(dāng)前內(nèi)容的高度比較,如果不一致,就說明軟鍵盤彈出:

 /**
     * 判斷是否軟鍵盤彈出
     * @return
     */
    private boolean isSoftShowing() {
        //獲取當(dāng)前屏幕內(nèi)容的高度(不會(huì)變)
        int screenHeight = getWindow().getDecorView().getHeight();
        //獲取View可見區(qū)域的bottom
        Rect rect = new Rect();
        getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);

        LogUtils.d(TAG, "screenHeight  = " + screenHeight + "  rect.bottom = " + rect.bottom);

        return screenHeight - rect.bottom != 0;
    }

2,為當(dāng)前界面的布局,添加一個(gè)onLayoutChange的接口,并將判斷邏輯添加到里面,例如:

@Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom,
                               int oldLeft, int oldTop, int oldRight, int oldBottom) {
        boolean isShowKeyBoard = isSoftShowing();
        LogUtils.d(TAG, "軟鍵盤是否彈出 : " + isShowKeyBoard);
        if (isShowKeyBoard) {
            mLoginLl.setTranslationY(-100);
        } else if (!isShowKeyBoard) {
            mLoginLl.setTranslationY(0);
        }
    }

附上一個(gè)在Github上比較使用的EditText

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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