android 软键盘显示和隐藏造成页面跳闪问题的解决方案
2019獨角獸企業重金招聘Python工程師標準>>>
一、分析問題
1.為什么會閃?
首先圖像切換主要用的無非就是ViewA.setVisibility(GONE) 和?ViewB.setVisbility(VISIBLE),如果不涉及到軟鍵盤,正常狀況下本就應該會閃,也就是說,只要有圖像切換,必會閃,這是正常的。
2.為什么會跳?
安卓的軟鍵盤SoftInput其實是一個dalog,它的彈出和縮回這兩個動畫是有持續時間的。當你切換界面的指令與顯隱鍵盤的指令操作過于接近時(也就是調了切換界面的方法后緊接著調了隱藏鍵盤的方法),會導致鍵盤還沒完成顯隱的操作時,切換頁面的操作缺已經執行完了。所以不管你先切換頁面還是先顯隱鍵盤,切換頁面的操作總是要比顯隱鍵盤先完成!
那么就造成了鍵盤還沒縮回,但頁面上會突然亂入一個View(View:你想切換到的頁面,或者你setVisibity(VISIBLE)的那個view),然后鍵盤才慢慢縮回,這樣從視覺效果上,就會錯覺View向上方閃一下,然后才出現在它該出現的位置。
二、解決方案:
1.非主流但很有意義的方案:
一開始我也在想,為啥手Q、微信、釘訂這些玩意的聊天切面就沒這個問題?在網上找方案,都是抄襲和轉載,還有很多所謂“高仿微信聊天鍵盤”等等的東西,都圍繞著ViewTreeObserver和GlobalLayoutListener,然后通過頁面板塊高度的減差計算得出鍵盤的高度,最后動態地設置顯示的頁面高度等于鍵盤高度,還要定死輸入框的高度。這種方案一看就是大牛寫出來,然后被各種轉載和抄襲的。此方案的好處很多,可以讓像我這樣的菜鳥深入到安卓底層,學到很多東西,而且符合觀察者模式。但是缺點也很明顯,就是邏輯復雜,代碼量大,效率低。
該方案教程:
https://my.oschina.net/JiangTun/blog/916027
2.微信、手Q這些玩意的主流解決方案:
有沒有更簡潔的方法呢?想到這,學院派應該會去找第三方包了吧。。但是作為一個野路子(苦逼完全自學派),為了理解里面的邏輯,為了減少包體積,為了提高效率增強動效,想到了去看環信的EaseUI源碼?
先看代碼,發現代碼寫的很有美感,很整齊清晰,邏輯也非常的清晰,這里給環信贊一個,但為啥文檔寫的那么屎?@環信?
對于鍵盤的處理,環信并沒有用ViewTreeObserver!
再看布局:
?
同樣只是用了android:layout_alignParentBottom="true"這個屬性而已,跟我沒有一點不同。
最后,順著event去找,終于發現了小秘密:
/*** show or hide emojicon*/ protected void toggleEmojicon() {if (chatExtendMenuContainer.getVisibility() == View.GONE) {hideKeyboard();handler.postDelayed(new Runnable() {public void run() {chatExtendMenuContainer.setVisibility(View.VISIBLE);chatExtendMenu.setVisibility(View.GONE);emojiconMenu.setVisibility(View.VISIBLE);}}, 50);} else {if (emojiconMenu.getVisibility() == View.VISIBLE) {chatExtendMenuContainer.setVisibility(View.GONE);emojiconMenu.setVisibility(View.GONE);} else {chatExtendMenu.setVisibility(View.GONE);emojiconMenu.setVisibility(View.VISIBLE);}} }可以看到,環信只是簡單的先隱藏了鍵盤,然后在50毫秒后才執行了切換頁面的操作,就是如此簡單!此時你再去看看我們前面分析的問題,會驚訝的發現這延后的50毫秒完美的解決了問題2!
拿起手機,觀察環信、微信、手Q,你還會發現另外一個共同的現象,就是它們的emoj區域和獲取媒體區域的高度都比系統軟鍵盤的高度要低!
那么最后總結一下就是:1.先隱藏軟鍵盤;2.隔上個幾十毫秒再切換頁面;3.頁面不要高于軟件盤的高度(一般在600以下)完活!
野路子精神萬歲!
3.最理想化的解決方案(未嘗試):
此方案應該是效率最高,頁面效果最為順滑的。不過我雖然想通了,但是最近項目時限緊,沒有時間去實現了,備注一下,以后試試!
經過觀察和調適,我發現,顯隱軟鍵盤會造成整個頁面重繪,并且切換布局會造成頁面重繪兩次(隱藏ViewA重繪一次,顯示ViewB再重繪一次),那么跳閃就可以理解為:在Activity前兩次重繪時,只是完成了view的切換,而第三次重繪才是改變鍵盤(第三次重繪時,給鍵盤施加了動畫)。
那么我們很容易就可以想到,如果把切換頁面和隱藏鍵盤放在同一個Acitity重繪中,不就看不到閃爍了嘛!!
順著這個思路想,我先想到了Activity,但是明顯dalog應該與activity同級,而鍵盤就是個dalog,那么目標就應該是activity的父級window對象了!
如果能找到鍵盤縮回的動畫,是不是就可以借用給界面?是不是就能時時監聽鍵盤高度變化?最后讓輸入框做個跟隨就行了!
想法很好,可惜沒空實現,先mark一下吧。
轉載于:https://my.oschina.net/JiangTun/blog/916955
總結
以上是生活随笔為你收集整理的android 软键盘显示和隐藏造成页面跳闪问题的解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [LeetCode]Count of R
- 下一篇: 移动html特殊链接【打电话_发短信_发