Android WebView輸入框被檔問題升級(jí)解析
前言
之前寫過一篇文章,有講如何處理Android輸入框被軟鍵盤擋住的問題,無論是原生的還是webview的,這里面主要的問題是webview的問題比較難處理,沒有看過的可以先看看 Android 輸入框被擋問題完美解決方案
主要是issue 5497這個(gè)問題。然后可能有些朋友覺得,這篇文章沒能解決他的問題,或者說按照我的代碼去寫又會(huì)出現(xiàn)新的問題。這說明沒有能理解這篇文章寫的內(nèi)容,我只是舉了一個(gè)自己碰到的場(chǎng)景,然后去分析,為什么會(huì)這樣,并用一些源碼告訴你為什么這樣寫的能解決。但是并不是所有的場(chǎng)景去套這個(gè)代碼都是正常的,不過如果你理解其中的一些原理的話,你至少能有個(gè)方向知道該從何下手去解決你自己碰到的場(chǎng)景。
如果看不懂沒關(guān)系,我這次講慢點(diǎn),再去慢慢分析更多的場(chǎng)景,但是有一點(diǎn)要記住,我對(duì)這個(gè)問題的處理不是萬金油,你必須要有一定的理解,知道一個(gè)方向,再去解決自己碰到的場(chǎng)景,不要直接套代碼。 這里分析的問題就是issue 5497這個(gè)問題。
issue 5497問題
我們?cè)俸?jiǎn)單回顧一下這個(gè)問題,原生的軟鍵盤和輸入框的沖突,直接設(shè)置window的softInputMode就能解決,這個(gè)很簡(jiǎn)單。但是如果輸入框是webview內(nèi)部H5的輸入框的情況下pan會(huì)失效,只能用resize。并且,如果是這個(gè)window是概念上全屏的情況下(設(shè)置全屏的方式很多),resize也會(huì)失效。
我上一篇文章中,我碰到的問題的場(chǎng)景是: 一個(gè)Dialog,里面的根頁(yè)面設(shè)置了沉浸模式,根布局下有一個(gè)webview,webview中有個(gè)輸入框,點(diǎn)擊輸入框時(shí)彈出軟鍵盤會(huì)擋住輸入框。
我們先分析,為什么會(huì)擋住輸入框?因?yàn)槟J(rèn)的softInputMode在正常情況下會(huì)頂起輸入框,但是webview會(huì)失效,那我們就把softInputMode設(shè)成SOFT_INPUT_ADJUST_RESIZE
然后發(fā)現(xiàn)沒效果,為什么沒效果?因?yàn)槲业腄ialog是全屏的,并且設(shè)置了沉浸模式,所以符合了全屏情況下resize也會(huì)失效這個(gè)條件。注意這個(gè)全屏可以理解成指的是概念上的全屏,不是我們視覺效果上的全屏,也就是這時(shí)去設(shè)置marginTop,通過這些方法去改變視覺上不是全屏是不會(huì)有效果的。
我們的思路就是破解讓這個(gè)window變成非全屏。 從上一篇文章可以看出,我們用的方法是設(shè)置fitSystemWindows,通過fitSystemWindows設(shè)置為true,來破解沉浸模式導(dǎo)致的全屏效果,原理是什么?通過上一篇文章知道,原理是設(shè)置一個(gè)安全距離,但是這個(gè)安全距離會(huì)導(dǎo)致你的window被壓縮,所以我們要重寫view的fitSystemWindows方法設(shè)置安全距離去防止window被壓縮
@Override
protected boolean fitSystemWindows(Rect insets) {
insets.top = 0;
return super.fitSystemWindows(insets);
}
而這個(gè)問題的解決思路是通過設(shè)置fitSystemWindows去打破全屏這個(gè)條件,從而使SOFT_INPUT_ADJUST_RESIZE能對(duì)webview生效。 這是重點(diǎn)的一步,后續(xù)的操作都是為了處理fitSystemWindows所帶來的影響。
布局頂起后距離軟鍵盤有一定距離
一般我們的布局頂起后底部也是緊貼軟鍵盤,有的朋友可能會(huì)說,為什么我也這樣做了,但是我webview布局被軟鍵盤頂起之后距離軟鍵盤會(huì)存在一部分的間距。
如果你不知道這個(gè)問題,說明對(duì)softInputMode不太理解,雖然我個(gè)人對(duì)這個(gè)理解也不是很深,但是如果你能使用SOFT_INPUT_ADJUST_PAN的話,就一定不會(huì)出現(xiàn)這個(gè)問題,但是用SOFT_INPUT_ADJUST_RESIZE的話,就會(huì)在某些布局中有這個(gè)問題,可惜上面說了,webview對(duì)SOFT_INPUT_ADJUST_PAN無效。
這是為什么呢?因?yàn)楹?jiǎn)單來說SOFT_INPUT_ADJUST_PAN是頂起你的輸入框,而SOFT_INPUT_ADJUST_RESIZE會(huì)把window給頂起來。所以如果你是window全屏并且webview也是全屏的情況就不會(huì)遇到這個(gè)問題(這里其實(shí)也就高度影響,寬度不影響),但如果你是window中的webview距離window的底部有一定的距離,這時(shí)候用SOFT_INPUT_ADJUST_RESIZE頂起來就會(huì)和輸入法有一段距離。
那這個(gè)問題要如何解決,這個(gè)解決的方法很多,比如通過邏輯手段,或者調(diào)整webview大小之類的,這個(gè)就沒什么好說的了。
Activity的webview輸入框被擋
上一篇文章包括上面有講我在Dialog中的webview的場(chǎng)景的解決方案。有的朋友會(huì)說我activity的webview也是這樣的,但是按照你這個(gè)代碼寫進(jìn)去沒有效果,我明明也給window設(shè)置了SOFT_INPUT_ADJUST_RESIZE,也給view設(shè)置了setFitsSystemWindows,也重寫了fitSystemWindows方法設(shè)置top,但是沒效果。
這就說明你還沒明白為什么會(huì)出現(xiàn)這個(gè)問題,你只是希望隨便去找個(gè)文章拷代碼下來用,代碼有用就覺得這個(gè)作者牛,代碼沒效果就覺得這個(gè)作者傻。好,哪怕你是不看為什么,只想考代碼,套到你使用的地方?jīng)]效果,那為何不問問為什么沒效果,你可以在評(píng)論區(qū)留言,說你是什么樣的場(chǎng)景,使用這個(gè)代碼沒效果。寫一兩句留言對(duì)你來說也并不耗多少時(shí)間,我只是覺得,解決問題,需要知道一個(gè)方向,不能一味的只想抄答案,這樣去解決問題是很耗費(fèi)時(shí)間的,而且這樣解決問題也可能會(huì)出現(xiàn)其它的問題。
有點(diǎn)扯遠(yuǎn)了,話說回來,為什么上面的代碼對(duì)Activity可能沒效果。如果認(rèn)真看都知道,我說了造成SOFT_INPUT_ADJUST_RESIZE失效的原因是全屏,而我上面Dialog的場(chǎng)景,造成全屏的操作是設(shè)置了沉浸模式,所以setFitsSystemWindows是為了處理沉浸模式導(dǎo)致全屏的情況。而你的Activity的全屏,不一定是沉浸模式造成的,所以你使用setFitsSystemWindows會(huì)無效。
還看不懂沒關(guān)系,再舉個(gè)例子。你給你的activity設(shè)置Fullscreen的主題theme也會(huì)導(dǎo)致全屏,這時(shí)候給window設(shè)置SOFT_INPUT_ADJUST_RESIZE無效,我們的思路是如何去破解Fullscreen這個(gè)主題造成的全屏。我們可以動(dòng)態(tài)去概念theme,行不行?當(dāng)然可以,但是這個(gè)時(shí)機(jī)要寫對(duì)。
我們也可以用window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN)去破解全屏的效果嘛。但是這個(gè)clearFlags如果對(duì)你的需求造成了影響,你還要通過其它方法去消除這個(gè)影響,這種就具體分析具體解決了,沒有標(biāo)準(zhǔn)的答案。
總結(jié)
寫這篇文章主要是想說明,這個(gè)webview被輸入法擋住的問題,這個(gè)issue 5497,是一個(gè)比較麻煩的問題,它不是光靠隨便在網(wǎng)上去抄個(gè)代碼就能解決的。包括你可能會(huì)去通過監(jiān)聽輸入法的彈出去計(jì)算滾動(dòng)的高度,這種方法理論上是不難,實(shí)際去開發(fā)也是要做一些細(xì)節(jié)處理和兼容的。
這篇文章沒有貼多少代碼,主要講一個(gè)解決問題的思路。要去理解這個(gè)問題是為什么發(fā)生的,知道一個(gè)方向,才能去更好的解決問題,你可以不按照我的代碼去寫,但是你知道解決問題的方向后,你甚至能自己通過適合自己業(yè)務(wù)的邏輯代碼去解決你的問題。
我不保證我對(duì)整個(gè)問題的理解是完全正確的,但是如果有大佬覺得我的理解有問題,可以指出,我也希望能這樣,這樣反而讓我印象更深刻。但是如果有人想不了解這些內(nèi)容的情況下通過去找別人的代碼去碰運(yùn)氣來解決問題,那我也只能祝你好運(yùn)。
以上就是Android WebView輸入框被檔問題升級(jí)解析的詳細(xì)內(nèi)容,更多關(guān)于Android WebView輸入框的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android 自定義Switch開關(guān)按鈕的樣式實(shí)例詳解
本文主要講的是在Android原生Switch控件的基礎(chǔ)上進(jìn)行樣式自定義,內(nèi)容很簡(jiǎn)單,但是在實(shí)現(xiàn)的過程中還是遇到了一些問題,在此記錄下來,需要的朋友參考下吧2017-12-12
Android 兩個(gè)ViewPager的聯(lián)動(dòng)效果的實(shí)現(xiàn)
這篇文章主要介紹了Android 兩個(gè)ViewPager的聯(lián)動(dòng)效果的實(shí)現(xiàn),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08
基于Android RecyclerView實(shí)現(xiàn)宮格拖拽效果
在Android發(fā)展的進(jìn)程中,網(wǎng)格布局一直比較有熱度,其中一個(gè)原因是對(duì)用戶來說便捷操作,對(duì)app廠商而言也會(huì)帶來很多的曝光量,本篇我們會(huì)使用RecyclerView來實(shí)現(xiàn)網(wǎng)格拖拽,本篇將結(jié)合圖片分片案例,實(shí)現(xiàn)拖拽效果,需要的朋友可以參考下2024-03-03
Flutter有無狀態(tài)類與State及生命周期詳細(xì)介紹
這篇文章主要介紹了Flutter無狀態(tài)類、有狀態(tài)類、State、生命周期,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09
Android 友盟第三方登錄與分享的實(shí)現(xiàn)代碼
這篇文章主要介紹了Android 友盟第三方登錄與分享的實(shí)現(xiàn)代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
Flutter開發(fā)之動(dòng)態(tài)權(quán)限的使用
眾所周知,Android在6.0版本后將權(quán)限修改成了動(dòng)態(tài)權(quán)限,而iOS則一直使用的是動(dòng)態(tài)權(quán)限,所以在Flutter應(yīng)用開發(fā)中如果涉及到一些危險(xiǎn)權(quán)限,就需要進(jìn)行動(dòng)態(tài)申請(qǐng),本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-09-09
Android自定義通用標(biāo)題欄CustomTitleBar
這篇文章主要為大家詳細(xì)介紹了Android自定義通用標(biāo)題欄CustomTitleBar,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
Android編程使用加速度傳感器實(shí)現(xiàn)搖一搖功能及優(yōu)化的方法詳解
這篇文章主要介紹了Android編程使用加速度傳感器實(shí)現(xiàn)搖一搖功能及優(yōu)化的方法,結(jié)合實(shí)例形式分析了Android傳感器的調(diào)用方法、參數(shù)含義及具體使用技巧,需要的朋友可以參考下2017-08-08

