如何正确理解Android的onScroll GestureDetector方法?

时间:2019-07-13 19:31:31

标签: android scroll onscroll gesturedetector onfling

在发表了几篇StackOverflow文章和Android的onScroll文档之后,我仍然无法理解onScroll方法的工作原理。

上下文以及我要实现的目标:我有一个Web视图,其中大部分是文本。我重写了Webview的默认滚动行为,而是尝试控制滚动机制。我希望能够-

  1. 用挥舞的手势滚动一段段落的长度。我可以通过调用Android的onFling方法来做到这一点。
  2. 使用拖动手势滚动到下一个句子。这就是我在努力的地方。

根据Android中拖动手势(加上滚动手势)的定义,拖动和甩动之间的区别在于,对于甩动,用户的手指必须以一定速度离开表面。话虽如此,我看到onScroll被多次调用,而onFling仅被调用一次。我想那没关系。我正在努力了解的是onScroll方法中的参数做什么?

我不太了解event1event2distanceXdistanceY的用途-如果每次onScroll叫。您如何理解这些参数?解释它们的正确方法是什么? Android文档没有帮助。

更新

我记录了我的触摸动作,这是它的外观。

移动:垂直向上拖动而无需抬起手指

event 1 X=600.64453, Y=891.5178
event 2 X=594.5489, Y=891.5178
event 1 X=600.64453, Y=886.3
event 2 X=593.7481, Y=886.3
event 1 X=600.64453, Y=879.9082
event 2 X=592.97614, Y=879.9082

问题:由于我是垂直向上移动的,所以我希望我的大部分更改都在Y轴上,而在X轴上却很少。我在这里看到的是,对于事件1,X始终相同,但是Y一直在变化。如果事件1是开始滚动的第一个下移动作,那么Y是否还应该相同?但是即使如此,您如何解释为什么这里的{event 1,event 2}中的任何一对X都不相同而Y相同?是不是应该相反?

移动:从左向右水平拖动。

event 1 X=340.66406, Y=861.7873
event 2 X=374.05276, Y=861.7873
event 1 X=340.66406, Y=862.9392
event 2 X=382.84317, Y=862.9392
event 1 X=340.66406, Y=864.10034
event 2 X=390.39926, Y=864.10034

问题:直觉说,在水平方向上的移动应该触发X轴上的大部分变化,而Y轴上的微小变化。在此,所有事件1 X相同,但Y不同。同样,我期望X和Y相同!对于{事件1,事件2}的任何一对,X都是不同的,而Y是相同的。这听起来很正常,但是如果再次回顾以上内容,我会感到困惑。您如何区分它们?

非常抱歉,我很抱歉道歉!

1 个答案:

答案 0 :(得分:0)

从文档中

/**
  * Notified when a scroll occurs with the initial on down {@link MotionEvent} and the
  * current move {@link MotionEvent}. The distance in x and y is also supplied for
  * convenience.
  *
  * @param e1 The first down motion event that started the scrolling.
  * @param e2 The move motion event that triggered the current onScroll.
  * @param distanceX The distance along the X axis that has been scrolled since the last
  *              call to onScroll. This is NOT the distance between {@code e1}
  *              and {@code e2}.
  * @param distanceY The distance along the Y axis that has been scrolled since the last
  *              call to onScroll. This is NOT the distance between {@code e1}
  *              and {@code e2}.
  * @return true if the event is consumed, else false
  */
  boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY);

e1:由于这是触发滚动的运动事件,因此可以期望在整个滚动中保持不变。

e2:用户可以沿多个方向在屏幕上移动手指而无需抬起它,并且onScroll会针对它检测到的每个更改分别调用。这非常敏感,所以这就是为什么您多次看到onScroll的原因。

distanceXdistanceY不是您的总旅行距离,而仅是自上次调用onScroll以来的距离。您可以通过比较每个MotionEvent上的getX()getY()方法来计算净距离。

如果您要做的只是检查滚动是否已启动,这可能是您需要的更多信息。您只有在收到唯一的event1

时,才能尝试触发事件