1. 程式人生 > >Android Scroller、scrollBy和scrollTo

Android Scroller、scrollBy和scrollTo

先說座標系

  • 檢視座標 Android view的檢視是沒有邊界的,也就是說canvas是沒有邊界的,可以無限繪製, 那麼這種無邊界的座標被成為檢視座標。(絕對座標,座標原點為螢幕左上角)
  • 佈局座標 也交相對座標,在View Layout時以當前view的左上角為座標原點 這裡盜一張圖 在這裡插入圖片描述

scrollBy和scrollTo

至於兩者的區別,網上很多詳細說明,就是scrollBy是滾動的一段距離(disx, disy), scrollTo是滾動到指定座標(direcx, direcy)。這裡說一些注意事項

  • scrollBy實際是呼叫的scrollTo 方法,所以兩者的實現是一樣的。
  • view的getScrollY()方法獲取的是scrollTo中設定的direcY也就是滾動的偏移量, 其絕對值是view實際滾動的距離,但是getScrollY()的值的符號與座標系符號相反
    , 比如當前從(0, 0)位置滾動到(100, 100)位置,偏移量是(0-100, 0-100)=(-100, -100)所以應該設定scrollTo(-100, -100)達到效果。 因此這個偏移量的符號與實際便宜終點位置減起始位置的符號相反。
  • 根據上一條,在處理TouchEvent時,傳入scrollTo的引數應該是終點位置減去起始位置的相反數,同理,獲取當前scrollOffset時也是getScrollY的相反數
  • scrollTo改變的是view中content的位置,而不會改變view的位置,view的位置是通過layout改變的,因此scrollTo不會影響getLeft等值。

再說scroller

scroller本身並不能讓view滾動,其滾動的本質還是呼叫view的scrollBy或者scrollTo方法,因此scroller的作用只是將滾動距離按照設定的時間間隔拆分一小段一小段,使得view滾動更加平滑。

Scroller涉及的方法

  • view的方法 invalidate() 重新整理介面, computeScroll() view滑動時會被父view呼叫該方法
  • scroller的方法
    • computeScrollerOffset() 該方法計算scroller在處理view滾動時的一些座標資訊。如果滾動結束該方法返回false, 否則返回true
    • startScroll(int startX, int startY, int dx, int dy) 該方法設定scroll的引數設定了view開始滾動的一些初始座標資訊startX, startY和滾動距離dx(水平方向,正數**content
      **向左滾, 負數向右) , dy(豎直方向, 正數 content向上,負數向下), 其實這裡的滾動方向都是由最後回撥的scrollBy方法決定的,而這裡的向上向下與上面的說的scrollBy引數的符號與正常座標計算的符號相反是一個道理。
  • fling(int startX, int startY, int velocityX, int velocityY, int minX, int maxX, int minY, int maxY)處理快速滑動的。startX, startY是指定一個初始的座標值,這個值可以隨意傳,但是在使用時要符合當時場景,前後一致。velocityX 橫向滑動速度,velocityY縱向滑動速度,單位 畫素/s。後面的min和max引數是滑動的最大x,y的座標

Scroller 的處理流程

  1. startScroll或者fling方法,設定滑動的一些初始和滑動資訊。
  2. 關鍵是呼叫invalidate()方法觸發view重繪關鍵是呼叫invalidate()方法觸發view重繪
  3. view繪製之前會呼叫view的computeScroll()方法,所以在該方法中呼叫scrollBy方法做實際的滾動操作。 example:
	@Override 
	public void computeScroll() { 
	    super.computeScroll(); 
	     if (mScroller.computeScrollOffset()) { 
	         scrollTo(mScroller.getCurrX(), 0); 
	         invalidate(); 
	     } 
	} 

注意在呼叫完scroll方法後要呼叫invalidate繼續後續重新整理