效果圖

隨著輸入的文本自動增加高度,鍵盤上方自定義選單布局,隨鍵盤彈起
點擊編輯框,自動滾動到焦點處輸入
布局層次
<ConstraintLayout>
<ScrollView>
<LinearLayout>
<Edittext/>
<自定義布局/>
</LinearLayout>
</ScrollView>
<鍵盤上方自定義布局/>
</ConstraintLayout>
想要實作自動焦點定位,需要手動計算滾動距離,系統也有自帶的滾動效果,不過因為這里有自定義布局,所以不兼容
系統原生自帶了鍵盤彈起頂起布局的方式,并且點擊 edittext 后 scrollView 里的 edittext 會自動滾動定位到焦點區域
有它的便捷也有它的問題,比如自定義鍵盤上方的布局后,定位不準確,因為自定義的布局不屬于鍵盤,系統不會計算在內,而且自動定位部分手機不起效果,需要做兼容
滾動后內容區域不在鍵盤上方自定義布局上,而是滾動到鍵盤上方,缺少了自定義布局的那段高度
滾動方法很簡單,直接呼叫 scrollView.smoothScrollTo(0, scrollTo) 方法就行
然后需要提前測量好鍵盤上方布局的高度跟鍵盤彈起的高度
鍵盤直接使用 Blankj 工具類 KeyboardUtils 監聽,布局高度直接測量就行
![]()
接下來監聽鍵盤彈起狀態 onSoftInputChanged,每次彈起鍵盤手動給 scrollView 設定 bottomMargin,為了讓布局在鍵盤彈起時在鍵盤上方位置,如果有自定義布局需要把布局高度也計算上

到這里鍵盤彈起結束,接下來進入核心,自動滾動定位焦點
首先是獲取到當前焦點的精確坐標,有了坐標才能跳轉
一開始我嘗試了 touch 觸摸事件,通過點擊的位置來獲取坐標,計算滑動距離,不過這個方案很快被推翻
因為不是很準確,加上內容是自適應高度,滑動距離過長時問題多
后來發現可以通過 getLineForOffset 方法獲取編輯框當前的行數,然后在通過 getLineBounds 方法獲取行坐標

獲取坐標后需要計算出 scrollView 滑動的距離
滑動距離 = 當前坐標 - 鍵盤彈起高度 + 自定義布局高度
如果沒有自定義布局就不用算
private fun scrollEdit() { //當前游標的坐標-鍵盤高度 val scrollTo = getCurrentEditY() - boardHeight + menuHeight mBinding.scrollView.post { //計算實際滾動的位置 mBinding.scrollView.smoothScrollTo(0, scrollTo) } }
得到滾動距離后直接在 onTextChanged 監聽里去呼叫上面的方法就行了,此時只要文本更改就會重新定位,自動滾動到你輸入的內容區域上
注意點
1、焦點自動定位問題
如果存在 ScrollView 嵌套 Edittext,那么會有部分手機系統會自動滾動到焦點位置的情況,但是這不符合我們的自定義需求,畢竟系統定位的不準確,沒有導航欄適配,
滾動的位置會出現遮擋鍵盤上方布局的情況,所以需要重寫方法去限制一下

2、導航欄適配問題
因為底部有自定義布局,會跟隨鍵盤彈起,所以需要適配系統導航欄,否則底部自定義布局不好適配
3、自動滾動問題
核心就在于滾動定位,需要自己計算滾動距離,并且在輸入的時候自動定位到該區域
并且如果呼叫滾動方法時,需要在變動之后呼叫,否則會跟系統測量結果有沖突,也就是在點擊后呼叫 post 方法,在里面做滾動操作
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/544381.html
標籤:Android
上一篇:Flutter筆記 - 事件分發
