關(guān)于android的各種花式鍵盤問題

首先鍵盤是什么,鍵盤其實(shí)是一個系統(tǒng)的dialog。當(dāng)她出現(xiàn)的時候肯定會對屏幕的尺寸造成影響。所以屏幕會重繪什么啊,移動什么的。

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

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

InputMethodManager?

和INPUT_METHOD_SERVICE進(jìn)行研究,由于這里只討論工程上的如何快速開發(fā)一個app,所以我等搬磚工只進(jìn)行應(yīng)用上的研究。

首先來總結(jié)一下,android應(yīng)用中有哪些關(guān)于鍵盤的需求。

1.隨手打開一個app就會發(fā)現(xiàn)這樣的需求


1-1

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


1-2

用戶點(diǎn)擊這個寫評論觸發(fā)了三個操作

1.EditText這個輸入框出現(xiàn),也就是visible。

2.鍵盤彈出。

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

一個一個的解決。

第一步很簡單,只需要在點(diǎn)擊"寫評論"的時候?qū)⑦@個EditText的狀態(tài)visible即可。

第二,彈出,我們先說說怎么彈出,這時候就涉及到了InputMethodManager?,F(xiàn)在具體說這個。

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

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

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

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

state表示的是軟鍵盤在狀態(tài)切換,比如activity跳轉(zhuǎn),view的重繪時候鍵盤的顯示或者隱藏。

"stateUnspecified": 默認(rèn)設(shè)置,沒有什么用,依賴于theme的默認(rèn)設(shè)置。

"stateUnchanged":當(dāng)這個activity出現(xiàn)時,軟鍵盤將一直保持在上一個activity里的狀態(tài),無論是隱藏還是顯示。

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

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

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

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

"adjustUnspecified":默認(rèn)設(shè)置,通常由系統(tǒng)自行決定是隱藏還是顯示

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

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

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

其實(shí)布局頂起的正確與否,與一下因素有關(guān):

當(dāng)一個activity繼承自Activity的時候:

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

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

非全屏模式一律不要加AndroidBug5497Workaround

當(dāng)一個activity繼承自AppCompatActivity的時候:

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

全屏模式下,也都是adjustPan效果。但是加了AndroidBug5497Workaround就可以實(shí)現(xiàn)adjustResize。但是測量的結(jié)果可能會有偏差。

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

1-3

1.adjustResize的時候,系統(tǒng)會重新計(jì)算布局,onMeasure,onSizeChanged,onLayout都會重新執(zhí)行,和adjustPan的區(qū)別方法是onSizeChanged會執(zhí)行。

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

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

目前來說,鍵盤還有幾個問題沒有得到優(yōu)化,后續(xù)會繼續(xù)進(jìn)行。

1.全屏與adjustResize之間的沖突,設(shè)置了全屏之后自己變?yōu)閍djustPan的效果了。(已解決,上面的內(nèi)容里有)

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

3.沉浸式狀態(tài)欄

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

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

https://github.com/Jacksgong/JKeyboardPanelSwitch

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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