完美解決EditText和ScrollView的滾動沖突(下)
上篇文章完美解決EditText和ScrollView的滾動沖突(上)中提到咱們自己寫了一個判斷EditText是否可以在垂直方向上滾動的方法,那么這個方法是如何得來的呢?
其實Android API里是有一個判斷控件是否可以在垂直方向上滾動的方法的,方法名字叫做canScrollVertically(int direction),代碼如下:
/**
* Check if this view can be scrolled vertically in a certain direction.
*
* @param direction Negative to check scrolling up, positive to check scrolling down.
* @return true if this view can be scrolled in the specified direction, false otherwise.
*/
public boolean canScrollVertically(int direction) {
final int offset = computeVerticalScrollOffset();
final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
if (range == 0) return false;
if (direction < 0) {
return offset > 0;
} else {
return offset < range - 1;
}
}
根據(jù)注釋不難得知此方法是用來判斷當前控件是否可以在垂直的方向上進行滾動的:當參數(shù)direction傳的是負值的時候,會判斷當前控件是否可以向上滾動;否則當參數(shù)direction傳的是非負值的時候,會判斷當前控件是否可以向下滾動。
由此得知我們完全可以利用此方法這樣來判斷一個控件是否可以在垂直方向上進行滾動:
if(editText.canScrollVertically(-1) || editText.canScrollVertically(0)) {
//垂直方向上可以滾動
}
那么為什么不使用此方法呢?很無奈,因為這個方法是在API 14(也就是Android4.0)才提供的方法,而很多時候我們需要兼容4.0以下的手機,所以并不能直接使用。雖然不能直接使用此方法,不過我們可以看一下它內部是怎么實現(xiàn)的,直接抄過來不就得了!不過還有個悲劇的消息,computeVerticalScrollOffset()、computeVerticalScrollRange()和computeVerticalScrollExtent()這三個方法都是protected方法,所以我們仍然不能使用,沒辦法,我們只好一塊兒將這三個方法內部的實現(xiàn)都看一下。
1.computeVerticalScrollOffset()方法
首先是computeVerticalScrollOffset()方法:`
protected int computeVerticalScrollOffset() {
return mScrollY;
}
此方法定義在View中,并且EditText和TextView都沒有重寫,所以其返回的必然是mScrollY。那么不適用這個方法我們該如何得到mScrollY呢?稍微猜測一下,既然有mScrollY這么一個變量,那么就應該有其的get方法。查看API,不難發(fā)現(xiàn)View中確實有個getScrollY()方法:
public final int getScrollY() {
return mScrollY;
}
2. computeVerticalScrollRange()方法
OK,第一個方法的值我們通過getScrollY()拿到了,接下來咱們來看第二個方法computeVerticalScrollRange():
protected int computeVerticalScrollRange() {
return getHeight();
}
在View中很快找到了此方法,但此方法使我們需要的嗎?不要忘了我們使用的是EditText!所以我們需要查看一下在EditText和TextView中是否對此方法進行了重載。不出我們所料,這個方法還真在TextView中進行了重載:
@Override
protected int computeVerticalScrollRange() {
if (mLayout != null)
return mLayout.getHeight();
return super.computeVerticalScrollRange();
}
這個方法返回的是mLayout的高度,那么我們怎么獲得mLayout呢?剛剛咱們獲得mScrollY時使用了getScrollY()方法,那么是不是會有一個getLayout()方法呢?抱著試試看的態(tài)度,忽然間發(fā)現(xiàn)在TextView中還真有這么一個方法:
public final Layout getLayout() {
return mLayout;
}
3.computeVerticalScrollExtent()方法
恩,第二個方法的值我們也通過getLayout().getHeight()方法拿到了,現(xiàn)在咱們就來看一下最后一個方法computeVerticalScrollExtent():
protected int computeVerticalScrollExtent() {
return getHeight();
}
在View中我們同樣找到了此方法,但根據(jù)第二個方法的經(jīng)驗,我們還應該去EditText和TextView中看一下有沒有重載。又一次地不出我們所料,這個方法果然在TextView中進行了重載:
@Override
protected int computeVerticalScrollExtent() {
return getHeight() - getCompoundPaddingTop() - getCompoundPaddingBottom();
}
然后不難發(fā)現(xiàn),此處使用的三個方法getHeight()、getCompoundPaddingTop()和getCompoundPaddingBottom()都是public方法,我們直接調用即可。
至此,我們已經(jīng)可以完全對canScrollVertically(int direction)這個方法進行重寫了,而重寫之后的方法就是咱們上一篇文章中使用的canVerticalScroll(EditText editText)方法。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
android使用flutter的ListView實現(xiàn)滾動列表的示例代碼
現(xiàn)如今打開一個 App,比如頭條、微博,都會有長列表,那么android使用flutter的ListView滾動列表如何實現(xiàn),本文就來詳細的介紹一下,感興趣的同學可以來了解一下2018-12-12
android使用DataBinding來設置空狀態(tài)
本篇文章主要介紹了android使用DataBinding來設置空狀態(tài),具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03
Android后臺啟動Activity的實現(xiàn)示例
這篇文章主要介紹了Android后臺啟動Activity的實現(xiàn)示例,幫助大家更好的理解和學習使用Android開發(fā),感興趣的朋友可以了解下2021-04-04
Android?Flutter實現(xiàn)頁面切換轉場動畫效果
Hero組件非常適合從列表、概覽頁切換到詳情頁轉場動畫場合。本文將利用Hero組件制作一個簡單的頁面切換轉場動畫效果,感興趣的可以了解一下2022-06-06
Android4.1中BinderService用法實例分析
這篇文章主要介紹了Android4.1中BinderService用法,以實例形式分析了Android4.1新增BinderService類的功能、原理及使用技巧,具有一定參考借鑒價值2015-10-10

