使用微信的朋友圈會發現,點擊某一條評論後輸入框會彈出來,而後所點擊的那一項會自動地滾動到輸入框上方的位置,這樣若是開始所點擊的評論在屏幕很下方的話,就不會被輸入框遮住,雖然微信這一點在個人MX2頻繁點幾回後滾動的位置就徹底錯誤了,但聽說在有些機型上效果還不錯,還有其餘地方可能會有相似的需求,好比登陸時軟鍵盤可能會把登陸按鈕遮住。html
要實現這個功能須要注意的地方主要有兩點:android
針對第一點,評論框出如今軟鍵盤的上方,通常狀況下軟鍵盤出來後評論框的位置會移動,也就是會出現Layout操做,因此能夠在Layout時計算滾動距離,時機就是:微信
view.getViewTreeObserver().addOnGlobalLayoutListener佈局
評論框Layout時的回調,在這裏計算須要滾動的距離。spa
接下來就是滾動距離的計算。server
滾動距離=所點擊的項底部的Y座標 - 軟鍵盤彈出後輸入框頂部的Y座標htm
因此只要知道這兩個座標就能夠知道須要滾動的距離,得到座標以很簡單,經過getGlobalVisibleRect就能夠了,固然還有其餘方法,但因爲是計算的差值,保證兩次計算座標時用同一個就能夠了。得到座標後直接smoothScrollBy。事件
原理就是這麼簡單,不過要實現起來,細節問題搞得人噁心。get
好比說輸入框初始的可見性多是GONE,也多是Visible,若是是GONE,那麼軟鍵盤彈出時可能會有兩個過程,1.從GONE到Visible會layout一次,2.軟鍵盤彈出又layout一次,隱藏時同樣。界面剛顯示時也會layout,因此這就須要判斷在onGlobalLayout時是否須要過濾事件。it
在MX2上實驗,smoothScrollBy有兩個參數,第二個是duration,若是duration太小,可能你傳入的distance是600,系統卻可能只會滾動500。
有時可能也須要在輸入框的onFocusChange中滾動。
若是到了列表底部,計算出的距離可能和實際滾動的距離也不同,這種狀況也能夠用setSelectionFromTop的方法讓所點擊的Item在屏幕最上方,固然也能夠再計算偏移,總之異常繁瑣。
若是是像登陸這種狀況,UI簡單的,要加個ScrollView,也比較好處理,軟鍵盤彈出時直接滾動到底部,隱藏時滾動到頂部。
總之,要實現自動滾動,首先就要有一個控件隨着軟鍵盤的彈出消失而移動位置,軟鍵盤彈出後出如今軟鍵盤的上方,哪怕它看不見只是做爲一個anchor。
其次,須要計算滾動距離,看狀況有所不一樣,也是最麻煩的,可能須要知道輸入框的狀態是隱藏,顯示在屏幕底部而軟鍵盤沒出來,仍是軟鍵盤出來了。不過在輸入框初始隱藏在佈局最下方的狀況下,這三種狀況輸入框的座標也只有3個值,也能夠根據這個值判斷輸入框的狀態,固然不排除有些輸入法能夠調整軟鍵盤高度而用戶又很配合地在輸入時調整。
反正若是有這需求就噁心死吧。在項目三個地方實現,大體方法都是同樣的,細節都有差別。