黑马程序员技术交流社区
标题: ListView 的 OverScrollBy 方法 detalY 与 scrollY 参数解析(上) [打印本页]
作者: Android_Robot 时间: 2016-11-7 11:01
标题: ListView 的 OverScrollBy 方法 detalY 与 scrollY 参数解析(上)
涨薪机密——新潮流新技术、新框架,资源以后不定期更新, ListView 的 OverScrollBy 方法 detalY 与 scrollY 参数解析
1. 为什么要分析这两个参数overScrollBy 翻译过来是“滚动越界后的变化”。这是一个在 View 里定义的方法 ,当 View 已经滚动到顶部或者底部之后,如果继续滑动,这个方法就会响应,方法参数传递了后续滚动的变化量。
但是在使用中发现在使用,当达到顶部后,由手指保持滑动和由惯性导致滑动,两种行为产生了有趣的数值变化,因此对其真实的数据含义进行了分析如下。
2. 基本数据
2.1自定义 MyListView 继承 ListView,覆写方法的如下。
[Java] 纯文本查看 复制代码
/**
* @param deltaY Change in Y in pixels。在Y方向变化的像素大小
* @param scrollY Current Y scroll value in pixels before applying deltaY。在应用deltaY之前的Y位置
*/
protected boolean overScrollBy(int deltaX, int deltaY,
int scrollX,int scrollY,
int scrollRangeX, int scrollRangeY,
int maxOverScrollX, int maxOverScrollY,
boolean isTouchEvent) {
System.out.println("deltaY="+deltaY+";scrollY="+scrollY+";isTouchEvent="+isTouchEvent);
return super.overScrollBy(deltaX, deltaY, scrollX, scrollY, scrollRangeX,scrollRangeY, maxOverScrollX, maxOverScrollY, isTouchEvent);
}
2.2 列表到达顶部的截图,出现闪烁的波纹即表示达到了列表顶部
3. 从 Log 猜测数据的含义
3.1 当到达顶部之后,由惯性导致滑动时的 Log 数据
[Java] 纯文本查看 复制代码
I/System.out: deltaY=-197; scrollY=0; isTouchEvent=false
I/System.out: deltaY=1; scrollY=-9; isTouchEvent=false
I/System.out: deltaY=1; scrollY=-8; isTouchEvent=false
I/System.out: deltaY=3; scrollY=-7; isTouchEvent=false
I/System.out: deltaY=2; scrollY=-4; isTouchEvent=false
I/System.out: deltaY=2; scrollY=-2; isTouchEvent=false
I/System.out: deltaY=0; scrollY=0; isTouchEvent=false
3.2 当到达顶端后,由手指继续滑动时的 Log 数据
[Java] 纯文本查看 复制代码
I/System.out: deltaY=-4; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-5; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-5; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-9; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-14; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-8; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-29; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-26; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-27; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-15; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-12; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-6; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-5; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-2; scrollY=0; isTouchEvent=true
I/System.out: deltaY=-1; scrollY=0; isTouchEvent=true
3.4 参数分析
首先,当惯性滑动时打印的 isTouchEvent 为 false,当手指继续滑动时 isTouchEvent 为 true。由此可以方便的区分滚动数据的来源。
其次,当惯性滑动时 scrollY 从 -9 变化为 0 ,可以理解是到达顶部之后列表弹动时Y轴的滚动变化。由手指滑动时始终为 0,因为此时列表并没有出现滚动。
最后,deltaY 的值根据注释可以知道是两次滚动之间的Y变化量,我们截取一段惯性滚动的 Log 来分析。
[Java] 纯文本查看 复制代码
I/System.out: deltaY=1; scrollY=-8; isTouchEvent=false
I/System.out: deltaY=3; scrollY=-7; isTouchEvent=false
I/System.out: deltaY=2; scrollY=-4; isTouchEvent=false
第一行和第二行的 scrollY 分别为 -8、-7,而第一行的 deltaY 为 1,确实是他们的差值。
第二行和第三行的 scrollY 分别为 -7、-4,而第二行的 deltaY 为 3,也确实是他们的差值。
也就是说 deltaY 是前后两次移动的差值 ,并且应该是 “新的Y位置 - 旧的Y位置” 。
3.5 奇怪的底层运算
从惯性滑动的 deltaY 算式,推断由手指拖拽时的 deltaY 值。虽然 Log 里的 scrollY 始终为 0,但是手指是由上向下滑动,可以假设开始时手指在 0,向下移动后达到 100,那么根据算式可以得到 “100 - 0 = 100”,但是从 Log 里可以看到,由手指造成的滚动 scrollY 始终为负值。
也就是他的表达式应该为 “旧的Y位置 - 新的Y位置”,这是第一个奇怪的地方,也就是滚动到列表顶部的 deltaY 算法似乎有多个。
第二个不合理在于,细看惯性滑动的 Log
[Java] 纯文本查看 复制代码
I/System.out: deltaY=1; scrollY=-8; isTouchEvent=false
I/System.out: deltaY=3; scrollY=-7; isTouchEvent=false
I/System.out: deltaY=2; scrollY=-4; isTouchEvent=false
第一行的 scrollY 为 -8,变化了 1 个像素,所以到第二行的时候 scrollY 变成了 -7。但是,这里的含义似乎是说“我根据当前的位置,计算出来一个变化量,然后滚动列表”。正常来说,应该是“我先移动列表,再根据上一次的位置来计算变化量”,从 Log 来看,是违背计算习惯的。
所以,研究这里的两个参数的运算方式也就比较有意思了。
年度最佳精华推荐奖:
跟随Android学科所有知识体系系统学习,无遗漏无瑕疵!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |