黑马程序员技术交流社区

标题: 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学习历史上最系统知识学习路线图
跟随Android学科所有知识体系系统学习,无遗漏无瑕疵!   
http://www.itheima.com/androidmap?srs







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2