秒懂Android開發之 android:windowSoftInputMode 屬性詳解

【版權申明】非商業目的可自由轉載
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/104232176
出自:shusheng007

概述

曾幾何時,你是否對軟鍵盤的顯示與隱藏,軟鍵盤與頁面佈局的關係傻傻分不清,測試的小姐姐時不時就會過來抱怨,

王二狗:
“你這個鍵盤怎麼把輸入框蓋住了,你讓我怎麼輸入啊?“
“你這個鍵盤怎麼把標題欄都頂沒了?”
“產品要求一進入這個頁面鍵盤就是要主動彈出來的,你這個沒有彈啊?”
“產品要求一進入這個頁面鍵盤是隱藏的,點擊輸入後才彈出,你這個爲什麼剛進來就彈出了呢?”

如果測試要真是個漂亮的小姐姐,倒也是一樁人間美事,說不定還能碰撞出愛情的小火花,那要是王姐,或者李姐之類胖大媽天天找你談心,你是不是就要瘋了?
所以,讓我們一起來徹底搞懂android:windowSoftInputMode吧,把握主動權!

windowSoftInputMode

android:windowSoftInputMode 一般是配置在AndroidManifest.xml中來設置軟鍵盤的行爲的,當然也可以通過代碼設置,如下所示

<activity android:name=".Activity2" android:windowSoftInputMode="stateUnspecified|adjustUnspecified"/>

android:windowSoftInputMode 的屬性值竟然多達10種,真是喪心病狂,但是仔細研究後發現也不是那麼不近人情,接下來就讓我們秒懂它吧。

其屬性分爲兩類:6個用來控制軟鍵盤的可見狀態,4個用來控制軟鍵盤與視圖window的佈局關係。

軟鍵盤可見性

假設有兩個Activity, Activity1Activity2

屬性值 含義
stateUnspecified 系統默認行爲,如果我們不在AndroidManifest設置windowSfotinputModle的值,默認就使用這個值,如果在App的主題(theme)中設置了屬性值,那麼系統就會採用主題裏的值,否則系統會根據不同的場景決定鍵盤的可見性。例如 Activity1中有一個EditText 進入此頁面不會顯示鍵盤,但是當使用ScrollView 包裹後,進入此頁面就會顯示鍵盤了
stateUnchanged 下一個界面的鍵盤顯示狀態與當前頁面保持一致。 例如Activity2設置了此屬性,現在從Activity1導航到Activity2,如果此時鍵盤是顯示的,那麼導航Activity2時也是顯示的,反之亦然
stateHidden 當一個Activity 被設置爲此屬性時,我們直接打開此界面鍵盤是隱藏的,但是從其他界面通過Activity棧返回的就不一定了。例如Activity1設置了此屬性,現在從Activity1導航到了Activity2,然後在Activity2中調出鍵盤,然後finish Activity2 回到Activity1,此時鍵盤就是顯示的了
stateAlwaysHidden 無論何種方式進入此頁面時,鍵盤都是隱藏的
stateVisible 和stateHidden類似,直接打開此頁面鍵盤是顯示的,但是從 其他界面通過Activity棧返回的就不一定了。例如Activity1設置了此屬性,現在從Activity1導航到了Activity2,然後在Activity2中隱藏鍵盤,然後finish Activity2 回到Activity1,此時鍵盤就是隱藏的了
stateAlwaysVisible stateAlwaysHidden類似,無論以何種方式進入此頁面,鍵盤都是顯示的

stateUnspecified

使用ScrollView包裹EditText系統默認會調出鍵盤

    <application
        ...>
        <activity android:name=".MainActivity" >
            ...
        </activity>
        ...
    </application>

在這裏插入圖片描述

stateUnchanged

    <application
        ...>
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="stateUnspecified">
            ...
        </activity>
        <activity android:name=".Activity1" android:windowSoftInputMode="stateUnchanged" />
        ...
    </application>

在這裏插入圖片描述

stateHidden

    <application
        ...>
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="stateHidden">
            ...
        </activity>
        <activity android:name=".Activity1" android:windowSoftInputMode="stateVisible" />
    </application>

在這裏插入圖片描述

stateAlwaysHidden

    <application
        ...>
        <activity android:name=".MainActivity"
            android:windowSoftInputMode="stateAlwaysHidden">
            ...
        </activity>
        <activity android:name=".Activity1" android:windowSoftInputMode="stateVisible" />
    </application>

在這裏插入圖片描述

stateVisible

與stateHind 相反

stateAlwaysVisible

與stateAlwaysHind 相反

軟鍵盤與Window的佈局關係

屬性值 含義
adjustResize 整個window 從底部整體擡升鍵盤的高度,頂部不會被頂上去,中間區域被下面頂上的內容覆蓋。這個效果和你的佈局方式有非常大的關係,在一些佈局方式中,是沒有效果的。
adjustPan 鍵盤會頂到輸入焦點下面,頂部都會被頂上去,輸入控件下面的內容會被覆蓋
adjustUnspecified 系統的默認設置,系統會根據佈局中是否有滾動佈局來覺得采用哪種方式,有滾動佈局:adjustResize 沒有滾動佈局adjustPan
adjustNothing 佈局不發生任何變化,鍵盤覆蓋在佈局上面

adjustResize

注意:其行爲與佈局方式相關,所以如果你發現這個屬性怎麼不起作用的時候,就回頭好好看看自己的佈局方式。
例如對於如下佈局的行爲見下面的gif圖

佈局1

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity2">
    <TextView
        android:id="@+id/tv_des"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第二個Activity"
        android:textColor="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="25dp"/>
    <EditText
        android:id="@+id/et_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toTopOf="@+id/tv_declare"
        android:layout_marginBottom="25dp"
        android:hint="輸入"/>
    <TextView
        android:id="@+id/tv_declare"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        android:layout_marginBottom="150dp"
        android:textColor="@color/colorPrimaryDark"
        android:textSize="15sp"
        android:text="ShuSheng007出品,必屬精品"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在這裏插入圖片描述
注意我們的EditText是以底部爲基準佈局的,其上面有可以覆蓋的空間,沒有定死。

我們再看一種佈局,這種佈局EditView 直接使用android:layout_marginTop="500dp"定死了,那這個屬性就不起作用了

佈局2

androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity2">
    <TextView
        android:id="@+id/tv_des"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第二個Activity"
        android:textColor="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="25dp"/>
    <EditText
        android:id="@+id/et_input"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_des"
        android:layout_marginTop="500dp"
        android:hint="輸入"/>
    <TextView
        android:id="@+id/tv_declare"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/et_input"
        android:textColor="@color/colorPrimaryDark"
        android:layout_marginTop="15dp"
        android:textSize="15sp"
        android:text="ShuSheng007出品,必屬精品"/>

</androidx.constraintlayout.widget.ConstraintLayout>

在這裏插入圖片描述
佈局3在佈局2的基礎上裏面加了ScrolView空間

佈局3

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Activity2">
    <TextView
        android:id="@+id/tv_des"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="第二個Activity"
        android:textColor="@color/colorAccent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="25dp"/>
    <ScrollView
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/tv_des"
        app:layout_constraintBottom_toBottomOf="parent">
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <EditText
                android:id="@+id/et_input"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                android:layout_marginTop="500dp"
                android:hint="輸入"/>
            <TextView
                android:id="@+id/tv_declare"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/et_input"
                android:layout_marginTop="15dp"
                android:textColor="@color/colorPrimaryDark"
                android:textSize="15sp"
                android:text="ShuSheng007出品,必屬精品"/>
        </androidx.constraintlayout.widget.ConstraintLayout>
    </ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>

在這裏插入圖片描述

adjustPan

對於佈局1 2 3 都起作用,且效果一致,真的很專一啊!
在這裏插入圖片描述

adjustNothing

沒什麼好演示的,彈出的軟鍵盤直接覆蓋在了window上。

如何使用

一個頁面的鍵盤可見性與佈局關係可以使用 | 來組合使用,如下所示。
<activity android:name=".Activity1" android:windowSoftInputMode="stateVisible|adjustResize" />

使用建議

一般情況下使用默認方式即可,特別是軟鍵盤佈局那塊,只通過調整我們自己的佈局來實現想要的效果。如果你的頂部欄被頂上去了,就好懷疑你的window是事實上使用了adjustPan方式。

總結

個人覺得這個可以關注了,雖然不難,但是真的是有用,遇到相關問題後可以回來查看一下,正所謂點點關注不迷路,天天都有小驚喜。

最後說一句,我想出去遛一遛,在家半個月了,憋死啦。。。

哪裏可以找到我?
Gitbub
個人博客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章