今天在做项目的时候,遇到一个问题,就是当数据量有成千上万行的时候,想要通过滚动列表实现的时候,不可能去实例化成千上万个Cell,这样对内存和效率都是暴击。那么唯一能做的就是把有限个Item在列表里不停的重复使用,来实现无限滚动。
NGUI下的滚动列表是用scrollview加grid或者table来实现的,在滑动列表的时候,grid是没有位移的,发生位移的是scrollview本身。grid底下的cell是按照CellWidth或者CellHeight来进行排序的。比如说我设置grid只有1列,cellHeight是100,那么第一个cell的位置是(0,0,0)
,第二个cell的位置就是(0,-100,0)
,第三个cell的位置是(0,-200,0)
,以此内推。垂直滚动的效果是通过scrollview沿Y轴移动来是实现的,grid作为scrollview的子节点,因此也跟着移动了,所以下边的cell会随着滚动出现在屏幕中间,同理,原来屏幕中间的cell就会滚动出屏幕。所以,无限滚动的原理就是当你使列表向上滑动时,把超出屏幕上边缘的cell移动到grid的最下方,当你使列表向下滑动时,把超出屏幕下边缘的cell,移动到grid的最上方,这样,就能用有限个cell实现无限滑动啦。
另一个问题是scrollview的自动吸附问题,假设每一屏就显示一个cell,我们希望每一次滑动都能够将一个cell完整的显示在屏幕中,而不会使一个屏幕显示2个cell的各一半。这个基本就是个算法问题,NGUI的scrollview有onDragStarted和onDragFinished,我们在这2个委托中去分别记录下开始拖动屏幕的时间,位置
和结束拖动时的时间和位置
,如果开始到结束的时间小于某个特定时间,比如0.5s,且手指位移超过固定值,比如50个像素,则我们认为是一次快速滑动,直接将scrollview按照滑动方向滚动到下一个cell的位置。如果不满足快速滑动的话,则将当前位置自动滑动到当前更靠近的cell的位置。