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,里面的根頁面設(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開發(fā)中TextView 實(shí)現(xiàn)右上角跟隨文本動(dòng)態(tài)追加圓形紅點(diǎn)
這篇文章主要介紹了android textview 右上角跟隨文本動(dòng)態(tài)追加圓形紅點(diǎn)的實(shí)例代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11Android viewpager中動(dòng)態(tài)添加view并實(shí)現(xiàn)偽無限循環(huán)的方法
這篇文章主要介紹了Android viewpager中動(dòng)態(tài)添加view并實(shí)現(xiàn)偽無限循環(huán)的方法,涉及Android使用viewpager動(dòng)態(tài)加載view及view無限循環(huán)顯示的相關(guān)技巧,需要的朋友可以參考下2016-01-01Kotlin類的繼承實(shí)現(xiàn)詳細(xì)介紹
這篇文章主要介紹了Kotlin類的繼承,在Java中類的繼承默認(rèn)是繼承父類的方法和參數(shù)的,但是在kotlin中默認(rèn)是不繼承的,那么我們接下來來驗(yàn)證2022-09-09Android原生項(xiàng)目集成React Native的方法
本篇文章主要介紹了Android原生項(xiàng)目集成React Native的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11Android實(shí)現(xiàn)短信驗(yàn)證碼自動(dòng)填寫功能
這篇文章主要介紹了Android實(shí)現(xiàn)短信驗(yàn)證碼自動(dòng)填寫功能,感興趣的小伙伴們可以參考一下2015-12-12詳解RecyclerView設(shè)置背景圖片長寬一樣(以GridLayoutManager為例)
這篇文章主要介紹了詳解RecyclerView設(shè)置背景圖片長寬一樣(以GridLayoutManager為例),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-12-12Android 取消藍(lán)牙配對(duì)框?qū)崿F(xiàn)自動(dòng)配對(duì)功能
這篇文章主要介紹了Android 取消藍(lán)牙配對(duì)框?qū)崿F(xiàn)自動(dòng)配對(duì)功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02Android關(guān)于BottomNavigationView使用指南
本文主要介紹了Android關(guān)于BottomNavigationView使用指南,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01