【View基礎知識】View的滑動之scrollTo、scrollBy
阿新 • • 發佈:2019-01-25
本系列文章部分摘自《Android開發藝術探索》,目的是提取精幹知識點加上自己部分理解作為備忘筆記,如有侵權請及時聯絡我,再次感謝作者,如喜歡請支援購買作者正版書籍
目錄
View的滑動方式
View 的滑動主要通過三種方式實現:
- 通過View本身提供的scrollTo/scrollBy
- 通過動畫實現View的滑動
- 通過改變View的LayoutParams使View重新佈局實現滑動
scrollTo/scrollBy實現的滑動
本篇文章主要記錄scrollTo/scrollBy實現的滑動
首先來看一段原始碼
/**
* Set the scrolled position of your view. This will cause a call to
* {@link #onScrollChanged(int, int, int, int)} and the view will be
* invalidated.
* @param x the x position to scroll to
* @param y the y position to scroll to
*/
public void scrollTo(int x, int y) {
if (mScrollX != x || mScrollY != y) {
int oldX = mScrollX;
int oldY = mScrollY;
mScrollX = x;
mScrollY = y;
invalidateParentCaches();
onScrollChanged(mScrollX, mScrollY, oldX, oldY);
if (!awakenScrollBars()) {
postInvalidateOnAnimation();
}
}
}
從原始碼我們可以看出:
- scrollBy實際上也是呼叫了scrollTo
- scrollTo使基於所傳引數的絕對滑動(比如:當前座標是(1,1)所傳引數x:2,y:2,最終會滑動到(2,2))
- scrollBy使基於當前位置的相對滑動(比如:當前座標是(1,1)所傳引數x:2,y:2,最終會滑動到(1+2,1+2))
scrollTo/scrollBy滑動的原理
上一篇中我解釋瞭如何用Scroller來實現彈性滑動,我們要理解利用scrollTo/scrollBy來時實現滑動不是一件難事,但是我們要明白滑動過程中View內部的兩個屬性mScrollX和mScrollY的改變規則,分別可以通過getScrollX、getScrollY獲得,需要說明幾點:
- 在滑動過程中,mScrollX的值總是等於View的左邊緣到View內容的左邊緣的水平距離(View左邊緣x - View內容左邊緣x),mScrollY的值總是等於View的上邊緣到View內容的上邊緣的豎直距離(View上邊緣y - View內容上邊緣y),這就證明了下面第4條的結論。
- View的邊緣是指View的的位置,有四個頂點組成,View內容邊緣是指View中內容的邊緣,具體如下所示。
- scrollTo/scrollBy只是改變了View中內容的位置,並沒有改變View的實際位置,可根據下圖理解。
- mScrollX/mScrollY單位是畫素,當View的左邊緣在View內容左邊緣左邊時,mScrollX為負數,反之則為正數;View上邊緣在View內容上邊緣上邊時mScrollY為負數,反之則為正數。換句話說:從左向右滑動時mScrollX為負數,反之則為正數;從上向下滑動時mScrollY為負數,反之則為正數,請結合1的結論理解;
根據上面的圖和我們的分析,可以知道,scrollTo/scrollBy來實現的滑動,只是使View中內容滑動,並沒有滑動View的實際位置,也就是不管怎麼滑動,都不會改變View的位置,這點要特別注意,比如:scrollTo/scrollBy實現滑動後,View的點選事件相應區域在什麼位置?