轉載地址:http://blog.csdn.net/qq_23933981/article/details/53993912
注意:
- 這兩個方法移動的並不是View本身。
- 如果該View沒有子View,那麼移動的就是View的內容(比如說調用一個Button的相應方法,會發現Button本身並不會移動,移動 的是Button的文本內容)。
- 如果該View中有子View,那麼移動的就是子View(比如說一個FrameLayout中有一個Button,調用FrameLayout的相應方法,會發現Button移動而FrameLayout不移動)
-
scrollTo(int, int)
讓View的content滾動到相對View初始位置的(x, y)處,可以看到這裏:mScrollX和mScrollY是保存這個view相對於起點座標的偏移量,如果這次傳進來的值和上一次滑動到的位置已經一致,則不做任何處理,如果不一樣則進行滑動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(); } } }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
方法名帶有to,給人的感覺就是移動到座標爲(x, y)的地方,其實實踐的結果並不是這樣,而是移動到偏移位置爲(x, y)的地方。那麼問題就來了,這個偏移是相對哪裏偏移呢?實踐結果是相對初始位置的偏移。
舉個例子,如果在當前佈局中存在一個Button,那麼此時的初始位置爲(0, 0),mScrollX和mScrollY均爲0。如果調用button.scrollTo(5, 5)的話,那麼移動後的位置就是“初始位置”減去“偏移位置”即:(x, y) = (0, 0) - (5, 5) = (-5, -5),所以button中的文字會向左向上分別移動5個像素。此時的mScrollX和mScrollY均爲5,因爲在源碼中可以看到mScrollX和mScrollY被賦值。如果再次調用button.scrollTo(5, 5),可以看到源碼會先進行判斷,當然自然是無法再次進入if代碼段。 -
scrollBy(int, int)
讓View的content滾動到相對於View當前位置的(x, y)處,這個方法實際是調用了上面的scrollTo方法,並且滑動的位置是上一次滑動到的位置加上傳入的偏移值,所以傳入的值如果不同時爲0,則肯定會觸發滑動public void scrollBy(int x, int y) { scrollTo(mScrollX + x, mScrollY + y); }
- 1
- 2
- 3
- 1
- 2
- 3
方法名帶有by,給人的感覺就是在當前位置的基礎上移動(x, y),這次沒問題,就是這樣移動的。這裏的偏移位置(x, y)就是相對於當前位置的偏移位置。
還拿上個例子來說,已經調用過一次button.scrollTo(5, 5)後再次調用會發現不會再移動,因爲無法再次進入if語句。如果此時調用button.scrollBy(5, 5)呢?可以看到源碼中分別給當前的mScrollX和mScrollY加了x和y,那麼此時傳入scrollTo方法的參數就是(10, 10),相當於直接調用了button.scrollTo(10, 10),在if語句判斷時就可以成功進入if語句。 -
總結
scrollTo()和scrollBy()的參數均爲偏移位置,不同之處在於scrollTo()的偏移位置是相對於初始位置的偏移位置,而scrollBy()的偏移位置是相對於當前位置的偏移位置。