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

相关文章
相关标签/搜索