之前做Symbian项目,由于软件的界面完全是自绘的,列表也是自绘,所以列表的滚动也要自己做,然后就试着做了两个引擎:
1.惯性滑动引擎:由于列表比较长,快速滑动,加速滑动。
2.弹性回归引擎:由于列表已经滑动到顶端(末端)需要再往下(往上)继续离开顶部(底部)一些距离,表示别表已无内容,列表到头。
当时做symbian的时候不知道Deceleration这个术语,本人只是从效果上看是惯性滑动,并且下拉的时候是回归动作。所以之前的名字是:惯性滑动,弹性回归!
基本思想就是按照每秒24帧的速度刷新列表,即每隔0.04秒刷新一次,由于是GC绘制,所以每次滑动时需要条用绘制函数,所以该引擎的效率还是不行。
这两天,将着两个引擎移植到iOS上发现,效果也不怎么滴。所以GC直接绘制效率太低。因为iOS上通常是使用“偏移量”来达到滑动效果。
相关文章: 探究contentOffset和contentInset,并解决上拉加载更多,uitableview抖动问题
第一、“惯性滑动”的思路
列表较长的情况下用手拨动屏幕,实现较长的滑动。但是这个滑动又不是线性的,还要有一些阻尼效果。
所以,第一次我想到了抛物线,是源自物体掉落的轨迹,后来经过测试这个效果不好。
于是,我又想到了标准正态分布曲线,这个阻尼效果更明显。如图1所示:
用户拨动屏幕,当手指离开屏幕时,必然带着初速度。那么我把这个初速度对应到图1中的Y轴最高点的值,然后这个值随着时间的推移,不断减小,从而达到模拟自然情况下阻尼滑动的效果。
如何求出初速度?
设计两个长度为5的数组,一个用于记录用户滑动时的坐标Y值。另外一个用于记录时间。不管用户滑动多长距离只保留最后5个坐标和5个时间值。然后,用户滑动的距离除以时间即可算出来速度。当然这里的单位就比较模糊了(严格上说是像素/微秒)。
还有一个技术点:如果用户在屏幕上来回滑屏,即轨迹并不是一个方向。这种情况怎么判断出来。如图2所示:
(图2)
判断最后5个点是否在同一条直线上。
第二、再说“弹性回归”的思路。
其实弹性回归要比惯性滑动复杂。为什么?因为,惯性滑动时,具体滑动的距离我不用关心,滑动多点儿也行,少点儿也行。但是弹性回归是一个固定的距离。比如:把列表从顶端往下拉动了100个像素,那么我的弹性回归引擎,需要在一定时间内按照某个曲线正好滑动完这100个像素。这次我选的是抛物线了,下面将详细说明理由。如下图3所示:100个像素就表示图中阴影部分的面积,弹性回归引擎要
(图3)
根据抛物线弓形面积公式等于:以割线为底,以平行于底的切线的切点为顶点的内接三角形的3/4,即: 抛物线弓形面积=S+1/4*S+1/16*S+1/64*S+……=4/3*S
根据阴影的面积可以求出,b的值。所以,每次滑动的距离即x1,x2,x3...x(b-1)。这里x1的面积需要微积分了。
总而言之:这两个引擎核心是两个曲线,仅供参考。这个方法也让公司申请了专利。专利号CN102331877A
代码我放到:http://download.csdn.net/detail/hherima/5161117
注意:该工程包含里富文本解析。只需要看MyList和BrowserSlideEngine.m就行了。