Android點擊列表后彈出輸入框,所點擊項自動滾動到輸入框上方


使用微信的朋友圈會發現,點擊某一條評論后輸入框會彈出來,然后所點擊的那一項會自動地滾動到輸入框上方的位置,這樣如果開始所點擊的評論在屏幕很下方的話,就不會被輸入框遮住,雖然微信這一點在我的MX2頻繁點幾次后滾動的位置就完全錯誤了,但據說在有些機型上效果還不錯,還有其他地方可能會有類似的需求,比如登錄時軟鍵盤可能會把登錄按鈕遮住。

要實現這個功能需要注意的地方主要有兩點:

  1. 什么時候進行滾動操作,以及有可能還需要在輸入框消失時回滾回去。
  2. 輸入框彈出后所點擊的項要滾動到輸入框上方,這就需要我們計算要滾動的距離。

針對第一點,評論框出現在軟鍵盤的上方,一般情況下軟鍵盤出來后評論框的位置會移動,也就是會出現Layout操作,所以可以在Layout時計算滾動距離,時機就是:

view.getViewTreeObserver().addOnGlobalLayoutListener

評論框Layout時的回調,在這里計算需要滾動的距離。

接下來就是滾動距離的計算。

滾動距離=所點擊的項底部的Y坐標 - 軟鍵盤彈出后輸入框頂部的Y坐標

所以只要知道這兩個坐標就可以知道需要滾動的距離,獲得坐標以很簡單,通過getGlobalVisibleRect就可以了,當然還有其他方法,但由於是計算的差值,保證兩次計算坐標時用同一個就可以了。獲得坐標后直接smoothScrollBy。

原理就是這么簡單,不過要實現起來,細節問題搞得人惡心。

比如說輸入框初始的可見性可能是GONE,也可能是Visible,如果是GONE,那么軟鍵盤彈出時可能會有兩個過程,1.從GONE到Visible會layout一次,2.軟鍵盤彈出又layout一次,隱藏時一樣。界面剛顯示時也會layout,所以這就需要判斷在onGlobalLayout時是否需要過濾事件。

在MX2上實驗,smoothScrollBy有兩個參數,第二個是duration,如果duration過小,可能你傳入的distance是600,系統卻可能只會滾動500。

有時可能也需要在輸入框的onFocusChange中滾動。

如果到了列表底部,計算出的距離可能和實際滾動的距離也不一樣,這種情況也可以用setSelectionFromTop的方法讓所點擊的Item在屏幕最上方,當然也可以再計算偏移,總之異常繁瑣。

如果是像登錄這種情況,UI簡單的,要加個ScrollView,也比較好處理,軟鍵盤彈出時直接滾動到底部,隱藏時滾動到頂部。

總之,要實現自動滾動,首先就要有一個控件隨着軟鍵盤的彈出消失而移動位置,軟鍵盤彈出后出現在軟鍵盤的上方,哪怕它看不見只是作為一個anchor。

其次,需要計算滾動距離,看情況有所不同,也是最麻煩的,可能需要知道輸入框的狀態是隱藏,顯示在屏幕底部而軟鍵盤沒出來,還是軟鍵盤出來了。不過在輸入框初始隱藏在布局最下方的情況下,這三種情況輸入框的坐標也只有3個值,也可以根據這個值判斷輸入框的狀態,當然不排除有些輸入法可以調整軟鍵盤高度而用戶又很配合地在輸入時調整。

反正如果有這需求就惡心死吧。在項目三個地方實現,大致方法都是一樣的,細節都有差異。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM