Android View 滾動機制

Android View 滾動機制

在Android中,若是出現須要展現的內容超過屏幕的大小,一般咱們會使用ScrollView和ListView來解決。本文將介紹這兩種方法的原理。android

ScrollView

咱們先看看mScrollX/mScrollY在代碼中的註釋:canvas

ScrollView註釋

mScrollX/mScrollY相對這個View的內容(文字,圖片,子View)垂直/水平的像素偏移。以下圖:緩存

ScrollView顯示空間

在設置mScrollX / mScrollY後,就能夠滾動到指定的「內容",而mScrollX/mScrollY 就是將內容原點(0,0)進行偏移的數值。函數

而這種內容大小以及偏移是如何發生的?在ViewGroup中,存在一個API drawChild(),這個函數主要完成對子View的空間大小的限制以及偏移,見以下的描述:rest

protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
	boolean more = false;
	//獲取子View的空間大小
	final int cl = child.mLeft;
	final int ct = child.mTop;
	final int cr = child.mRight;
	final int cb = child.mBottom;
	//通知子View進行判斷是否完成滾動,這裏就是經過Scroller代碼實現滾動的關鍵點
	child.computeScroll();
	//獲取最新的偏移量
	final int sx = child.mScrollX;
	final int sy = child.mScrollY;
	//建立一個還原點
	final int restoreTo = canvas.save();
	//偏移,經過這個API,實現了scroll對內容偏移, 先把內容的原點進行偏移到負數區域
	canvas.translate(cl - sx, ct - sy);
	//剪切,由於以前有一個translate操做,全部剪切出來的空間就是父View給定的可見區域
	//因此若是子View填充Canvas的內容超出給定的空間,也不會顯示出來
	canvas.clipRect(sx, sy, sx + (cr - cl), sy + (cb - ct));
	//讓子View進行繪圖,注意子View不用處理Scroll屬性,既能夠實現內容偏移
	child.draw(canvas);
	//還原
	canvas.restoreToCount(restoreTo);
	return more;
}

經過設置canvas的可見區域以及偏移平移座標原點(0,0),就能夠完成在固定大小內經過滾動顯示被覆蓋的部分。code

ListView

ListView和ScrollView有很大的區別:ListView僅僅須要幾個View既能夠實現滾動效果,而ScrollView須要所有的View。咱們來看一下ListView緩存機制:圖片

ListView緩存機制

因此ListView的滾動效果是經過替換ViewGroup上的子View來實現的。ip

總結

在android中,爲了實現滾動效果,一般有兩種方式:原理

  • 經過scrollTo實現
  • 經過替換ViewGroup上的子View實現

而ScrollView和ListView就是這兩種實現的表明了。cli

相關文章
相關標籤/搜索