【版權申明】非商業目的可自由轉載
博文地址: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, Activity1 和Activity2
屬性值 | 含義 |
---|---|
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
方式。
總結
個人覺得這個可以關注了,雖然不難,但是真的是有用,遇到相關問題後可以回來查看一下,正所謂點點關注不迷路,天天都有小驚喜。
最後說一句,我想出去遛一遛,在家半個月了,憋死啦。。。