關于android的各種花式鍵盤問題

首先鍵盤是什么,鍵盤其實是一個系統的dialog。當她出現的時候肯定會對屏幕的尺寸造成影響。所以屏幕會重繪什么啊,移動什么的。

特別特別重要的一點,調用系統顯示鍵盤的方法時一定要先requestFocus這個editText的焦點。不然會出現一些怪異的事情,比如你掉了顯示鍵盤,他也不會彈出。

關于鍵盤是android的一個比較大的問題,像搜狗,百度都是自己的輸入法,這些都是需要對android的InputMethodManager進行深入的研究,當然首先肯定是看API

InputMethodManager?

和INPUT_METHOD_SERVICE進行研究,由于這里只討論工程上的如何快速開發一個app,所以我等搬磚工只進行應用上的研究。

首先來總結一下,android應用中有哪些關于鍵盤的需求。

1.隨手打開一個app就會發現這樣的需求


1-1

點擊這個"寫評論"就會彈出一個輸入框,并且輸入法需要將這個輸入框頂上去。是這樣的。


1-2

用戶點擊這個寫評論觸發了三個操作

1.EditText這個輸入框出現,也就是visible。

2.鍵盤彈出。

3.鍵盤將這個EditText頂上去。

一個一個的解決。

第一步很簡單,只需要在點擊"寫評論"的時候將這個EditText的狀態visible即可。

第二,彈出,我們先說說怎么彈出,這時候就涉及到了InputMethodManager。現在具體說這個。

InputMethodManager,正如它的名字一樣,是一個鍵盤的管理者,里面有一些和變量可以操作鍵盤。包括打開,強制關閉等操作。具體代碼在github的demo里,注釋寫的很詳細了。

第三,彈出的時候需要將這個visible的edittext頂上去,這時候設計到了一個屬性叫windowSoftInputMode。

一定要注意理解windowSoftInputMode的每一個屬性的意思。

一般是state屬性和adjust屬性一起用,之間用 | 隔開。

state表示的是軟鍵盤在狀態切換,比如activity跳轉,view的重繪時候鍵盤的顯示或者隱藏。

"stateUnspecified": 默認設置,沒有什么用,依賴于theme的默認設置。

"stateUnchanged":當這個activity出現時,軟鍵盤將一直保持在上一個activity里的狀態,無論是隱藏還是顯示。

"stateHidden":當跳轉一個activity的時候,鍵盤是hide的。注意是跳轉而不是finish,也就說startActivity的時候當前鍵盤hide,但是當你finish當前activity,鍵盤不會消失。

"stateAlwaysHidden":不管什么,只要activity的主窗口獲得焦點,鍵盤就hide。

"stateVisible":軟鍵盤通常是可見的

"stateAlwaysVisible":上面的通常變成always。

"adjustUnspecified":默認設置,通常由系統自行決定是隱藏還是顯示

"adjustResize": 會重新繪制view,onSizeChanged會重新調用,注意adjustPan這個方法不會調用。

"adjustPan":設置成adjustPan的時候鍵盤會去找當前界面的焦點,并始終焦點放在鍵盤的上方,使獲得焦點的view可見。當前窗口的內容將自動移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分

adjustResize 和 adjustPan 的目的很簡單,他們兩個都是做一切的努力想要為這個帶有焦點的editText留出空間,讓他出現,adjustPan采用的是一種平移屏幕的方式,將editText放在鍵盤上,adjustResize采用的是壓縮屏幕的方式留出空間。為了留出空間,用心良苦啊。

其實布局頂起的正確與否,與一下因素有關:

當一個activity繼承自Activity的時候:

非全屏模式下,一切正常。

全屏模式下,不管你是adjustXXX,最后的效果都是adjustPan。AndroidBug5497Workaround

非全屏模式一律不要加AndroidBug5497Workaround

當一個activity繼承自AppCompatActivity的時候:

非全屏模式下,一切正常。

全屏模式下,也都是adjustPan效果。但是加了AndroidBug5497Workaround就可以實現adjustResize。但是測量的結果可能會有偏差。

這里要注意幾點:(如下這張圖片就是下面所講的內容布局,寫評論就是那個editText)

1-3

1.adjustResize的時候,系統會重新計算布局,onMeasure,onSizeChanged,onLayout都會重新執行,和adjustPan的區別方法是onSizeChanged會執行。

需要彈出的editText輸入框不管怎么樣都要放到原始布局的最下方。內容布局最好用ScrollView來包裹,這時候即使彈出也不會對內容布局造成任何影響。如果用別的布局代替ScrollView的話,內容布局就會按比例的壓縮到一起,效果不好。原因是該Activity總是調整屏幕的大小以便留出軟鍵盤的空間

2.一個怪異的問題是,當這個editText的background只有color,那么adjustResize不會有問題,但是adjustPan的時候,會遮擋住editText下部的一小部分,但是當這個background是一張.9圖的時候顯示正常,我猜想,當時介紹adjustPan的時候說了,他只是努力將移動以便當前焦點從不被鍵盤覆蓋和用戶能總是看到輸入內容的部分,他想著我你看到哪個光標也就是焦點了吧,那好我不移了。

目前來說,鍵盤還有幾個問題沒有得到優化,后續會繼續進行。

1.全屏與adjustResize之間的沖突,設置了全屏之后自己變為adjustPan的效果了。(已解決,上面的內容里有)

2.底部有虛擬鍵盤的情況

3.沉浸式狀態欄

2和3提到的問題,如果處理不了其實就是對于android的沉浸式,透明Navagation,還有android的window的view組成掌握的不熟悉,對AndroidBug5497Workaround不熟悉。。請到下幾篇文章(詳解AndroidBug5497Workaround,android的深層布局結構)里搞一搞,自己懂了原理自然就懂了。

4.鍵盤出現的時候布局閃動的問題,下一篇文章里會講。具體的原理依據以下源碼。

https://github.com/Jacksgong/JKeyboardPanelSwitch

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

推薦閱讀更多精彩內容