Android鍵盤面板衝突 佈局閃動處理方案
這次主要是根據核心思想的實踐,實踐原理是通過
CustomRootLayout
佈局變化,來獲知是否是鍵盤引起的真正的佈局變化,進而處理到接下來PanelLayout
的onMersure
中。
- 新演算法不再動態修改
View#LayoutParams
,而是更加簡單明瞭的方式 - 最新程式碼在原基礎上自動動態適配面板高度與鍵盤高度等高,很大程度上優化了體驗。
我們可以看到微信中的 從鍵盤與微信的切換是無縫的,而且是無閃動的,這種基礎體驗是符合預期的。
但是實際中,簡單的 鍵盤與面板切換 是會有閃動,問題的。今天我們就實踐分析與解決這個問題。
最終效果對比:
I. 準備
以下建立在
android:windowSoftInputMode
帶有adjustResize
的基礎上。如圖,為了方便分析,我們分出3個View:
CustomRootView
: 除去statusBar與ActionBar(ToolBar…balabala)FootRootView
: 整個底部(包括輸入框與底部面板在內的整個View)PanelView
: 面板View
整個處理過程,其實需要分為兩塊處理:
- 從
PanelView
切換到Keybord
現象: 由於顯示Keybord
時直接PanelView#setVisibility(View.GONE)
,導致會出現整個FooterRootView
到底部然後又被鍵盤頂起。
符合預期的應該: 直接被鍵盤頂起,不需要到底部再頂起。
- 從
Keybord
切換到PanelView
現象: 由於隱藏Keybord
時,直接PanelView#setVisibility(View.VISIBLE)
,導致會出現整個FootRootView
先被頂到鍵盤上面,然後再隨著鍵盤的動畫,下到底部。
符合預期的應該: 隨著鍵盤收下直接切換到底部,而配有被鍵盤頂起的閃動。
II. 處理
原理
在真正由Keybord
導致佈局真正將要變化的時候,才對PanelView
做出適配。(注意,所有的判斷處理要在Super.onMeasure
之前完成判斷)
方法:
通過
CustomRootView
高度的變化,來保證在Super.onMeasure
之前獲得真正的由於鍵盤導致佈局將要變化,然後告知PanelView
,讓其在Super.onMeasure
之前給到有效高度。
需要注意:
1) 在
adjustResize
模式下,鍵盤彈起會導致CustomRootView
的高度變小,鍵盤收回會導致CustomRootView
的高度變大,反之變小。因此可以通過這個機制獲知真正的PanelView
將要變化的時機。2) 由於到了
onLayout
,clipRect的大小已經確定了,又要避免不多次呼叫onMeasure
因此要在Super.onMeasure
之前3) 由於鍵盤收回的時候,會觸發多次
measure
,如果 不判斷真正的由於鍵盤收回導致佈局將要變化,就直接給View#VISIBLE
,依然會有閃動的情況。4) 從
Keybord
切換到PanelView
導致的佈局衝突,只有在Keybord
正在顯示的時候。5) 從
PanelView
切換到Keybord
導致的佈局衝突,已經在PanelView
與CustomRootView
中內部處理。
III. GitHub:
© 2012 - 2016, Jacksgong(blog.dreamtobe.cn). Licensed under the Creative Commons Attribution-NonCommercial 3.0 license (This license lets others remix, tweak, and build upon a work non-commercially, and although their new works must also acknowledge the original author and be non-commercial, they don’t have to license their derivative works on the same terms).http://creativecommons.org/licenses/by-nc/3.0/