完美解決EditText和ScrollView的滾動(dòng)沖突(下)
上篇文章完美解決EditText和ScrollView的滾動(dòng)沖突(上)中提到咱們自己寫了一個(gè)判斷EditText是否可以在垂直方向上滾動(dòng)的方法,那么這個(gè)方法是如何得來(lái)的呢?
其實(shí)Android API里是有一個(gè)判斷控件是否可以在垂直方向上滾動(dòng)的方法的,方法名字叫做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ù)注釋不難得知此方法是用來(lái)判斷當(dāng)前控件是否可以在垂直的方向上進(jìn)行滾動(dòng)的:當(dāng)參數(shù)direction傳的是負(fù)值的時(shí)候,會(huì)判斷當(dāng)前控件是否可以向上滾動(dòng);否則當(dāng)參數(shù)direction傳的是非負(fù)值的時(shí)候,會(huì)判斷當(dāng)前控件是否可以向下滾動(dòng)。
由此得知我們完全可以利用此方法這樣來(lái)判斷一個(gè)控件是否可以在垂直方向上進(jìn)行滾動(dòng):
if(editText.canScrollVertically(-1) || editText.canScrollVertically(0)) { //垂直方向上可以滾動(dòng) }
那么為什么不使用此方法呢?很無(wú)奈,因?yàn)檫@個(gè)方法是在API 14(也就是Android4.0)才提供的方法,而很多時(shí)候我們需要兼容4.0以下的手機(jī),所以并不能直接使用。雖然不能直接使用此方法,不過(guò)我們可以看一下它內(nèi)部是怎么實(shí)現(xiàn)的,直接抄過(guò)來(lái)不就得了!不過(guò)還有個(gè)悲劇的消息,computeVerticalScrollOffset()、computeVerticalScrollRange()和computeVerticalScrollExtent()這三個(gè)方法都是protected方法,所以我們?nèi)匀徊荒苁褂?,沒辦法,我們只好一塊兒將這三個(gè)方法內(nèi)部的實(shí)現(xiàn)都看一下。
1.computeVerticalScrollOffset()方法
首先是computeVerticalScrollOffset()方法:`
protected int computeVerticalScrollOffset() { return mScrollY; }
此方法定義在View中,并且EditText和TextView都沒有重寫,所以其返回的必然是mScrollY。那么不適用這個(gè)方法我們?cè)撊绾蔚玫絤ScrollY呢?稍微猜測(cè)一下,既然有mScrollY這么一個(gè)變量,那么就應(yīng)該有其的get方法。查看API,不難發(fā)現(xiàn)View中確實(shí)有個(gè)getScrollY()方法:
public final int getScrollY() { return mScrollY; }
2. computeVerticalScrollRange()方法
OK,第一個(gè)方法的值我們通過(guò)getScrollY()拿到了,接下來(lái)咱們來(lái)看第二個(gè)方法computeVerticalScrollRange():
protected int computeVerticalScrollRange() { return getHeight(); }
在View中很快找到了此方法,但此方法使我們需要的嗎?不要忘了我們使用的是EditText!所以我們需要查看一下在EditText和TextView中是否對(duì)此方法進(jìn)行了重載。不出我們所料,這個(gè)方法還真在TextView中進(jìn)行了重載:
@Override protected int computeVerticalScrollRange() { if (mLayout != null) return mLayout.getHeight(); return super.computeVerticalScrollRange(); }
這個(gè)方法返回的是mLayout的高度,那么我們?cè)趺传@得mLayout呢?剛剛咱們獲得mScrollY時(shí)使用了getScrollY()方法,那么是不是會(huì)有一個(gè)getLayout()方法呢?抱著試試看的態(tài)度,忽然間發(fā)現(xiàn)在TextView中還真有這么一個(gè)方法:
public final Layout getLayout() { return mLayout; }
3.computeVerticalScrollExtent()方法
恩,第二個(gè)方法的值我們也通過(guò)getLayout().getHeight()方法拿到了,現(xiàn)在咱們就來(lái)看一下最后一個(gè)方法computeVerticalScrollExtent():
protected int computeVerticalScrollExtent() { return getHeight(); }
在View中我們同樣找到了此方法,但根據(jù)第二個(gè)方法的經(jīng)驗(yàn),我們還應(yīng)該去EditText和TextView中看一下有沒有重載。又一次地不出我們所料,這個(gè)方法果然在TextView中進(jìn)行了重載:
@Override protected int computeVerticalScrollExtent() { return getHeight() - getCompoundPaddingTop() - getCompoundPaddingBottom(); }
然后不難發(fā)現(xiàn),此處使用的三個(gè)方法getHeight()、getCompoundPaddingTop()和getCompoundPaddingBottom()都是public方法,我們直接調(diào)用即可。
至此,我們已經(jīng)可以完全對(duì)canScrollVertically(int direction)這個(gè)方法進(jìn)行重寫了,而重寫之后的方法就是咱們上一篇文章中使用的canVerticalScroll(EditText editText)方法。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android使用flutter的ListView實(shí)現(xiàn)滾動(dòng)列表的示例代碼
現(xiàn)如今打開一個(gè) App,比如頭條、微博,都會(huì)有長(zhǎng)列表,那么android使用flutter的ListView滾動(dòng)列表如何實(shí)現(xiàn),本文就來(lái)詳細(xì)的介紹一下,感興趣的同學(xué)可以來(lái)了解一下2018-12-12android使用DataBinding來(lái)設(shè)置空狀態(tài)
本篇文章主要介紹了android使用DataBinding來(lái)設(shè)置空狀態(tài),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-03-03安卓中出現(xiàn)過(guò)的一些容易被忽略的異常整理
今天小編就為大家分享一篇關(guān)于安卓中出現(xiàn)過(guò)的一些容易被忽略的異常整理,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-12-12AndroidQ(10)分區(qū)存儲(chǔ)完美適配方法
這篇文章主要介紹了AndroidQ(10)分區(qū)存儲(chǔ)完美適配方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
這篇文章主要介紹了Android Bluetooth藍(lán)牙技術(shù)使用流程詳解的相關(guān)資料,需要的朋友可以參考下2016-02-02Android后臺(tái)啟動(dòng)Activity的實(shí)現(xiàn)示例
這篇文章主要介紹了Android后臺(tái)啟動(dòng)Activity的實(shí)現(xiàn)示例,幫助大家更好的理解和學(xué)習(xí)使用Android開發(fā),感興趣的朋友可以了解下2021-04-04android幾種不同對(duì)話框的實(shí)現(xiàn)方式
這篇文章介紹了android幾種不同對(duì)話框的實(shí)現(xiàn),主要包括:1、顯示提示消息的對(duì)話框.2、簡(jiǎn)單列表項(xiàng)對(duì)話框。3、單選列表項(xiàng)對(duì)話框。4、多選列表對(duì)話框。5、自定義列表項(xiàng)對(duì)話框。6、自定義View的對(duì)話框,需要的朋友可以參考下2015-08-08Android?Flutter實(shí)現(xiàn)頁(yè)面切換轉(zhuǎn)場(chǎng)動(dòng)畫效果
Hero組件非常適合從列表、概覽頁(yè)切換到詳情頁(yè)轉(zhuǎn)場(chǎng)動(dòng)畫場(chǎng)合。本文將利用Hero組件制作一個(gè)簡(jiǎn)單的頁(yè)面切換轉(zhuǎn)場(chǎng)動(dòng)畫效果,感興趣的可以了解一下2022-06-06Android4.1中BinderService用法實(shí)例分析
這篇文章主要介紹了Android4.1中BinderService用法,以實(shí)例形式分析了Android4.1新增BinderService類的功能、原理及使用技巧,具有一定參考借鑒價(jià)值2015-10-10