View 的 OverScrollBy 方法

  1. 在 AbsListView、HorizontalScrollView、ScrollView 的 onTouchEvent 中判断是否到达边界(顶部 或 底部) ,然后调 view.overScrollBy ,传入 scrollX、scrollY 等参数
  2. overScrollBy 最终赋值给View的 mScrollX, mScrollY 两个变量
  3. 在AbsListView中调用完overScrollBy之后,调用invalidate重绘

/**
* 当 View 滚动超过了 View 的内容边界的时候, 该方法可以使用统
* 一的标准的行为来滚动 view。调用这个方法的 View 应该重写
* onOverScrolled 方法来响应滚动越界的行为。View 可以使用这个
* 方法来处理任何 touch 和 fling 的滚动
*
* @param deltaX Change in X in pixels scrollx 变化量
* @param deltaY Change in Y in pixels
* @param scrollX Current X scroll value in pixels before applying deltaX 在应用 deltaX 之前的当前 scrollX 值
* @param scrollY Current Y scroll value in pixels before applying deltaY
* @param scrollRangeX Maximum content scroll range along the X axis scrollX 的最大滚动范围
* @param scrollRangeY Maximum content scroll range along the Y axis
* @param maxOverScrollX Number of pixels to overscroll by in either direction scrollX 的最大超出值
* along the X axis.
* @param maxOverScrollY Number of pixels to overscroll by in either direction
* along the Y axis.
* @param isTouchEvent true if this scroll operation is the result of a touch event. 是否正在触摸
* @return true if scrolling was clamped to an over-scroll boundary along either
* axis, false otherwise.
*/

@SuppressWarnings({"UnusedParameters"})
protected boolean overScrollBy(int deltaX, int deltaY,
        int scrollX, int scrollY,
        int scrollRangeX, int scrollRangeY,
        int maxOverScrollX, int maxOverScrollY,
        boolean isTouchEvent) {
    final int overScrollMode = mOverScrollMode;
    final boolean canScrollHorizontal =
            computeHorizontalScrollRange() > computeHorizontalScrollExtent();
    final boolean canScrollVertical =
            computeVerticalScrollRange() > computeVerticalScrollExtent();
    final boolean overScrollHorizontal = overScrollMode == OVER_SCROLL_ALWAYS ||
            (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollHorizontal);
    final boolean overScrollVertical = overScrollMode == OVER_SCROLL_ALWAYS ||
            (overScrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && canScrollVertical);

    int newScrollX = scrollX + deltaX;
    if (!overScrollHorizontal) {
        maxOverScrollX = 0;
    }

    int newScrollY = scrollY + deltaY;
    if (!overScrollVertical) {
        maxOverScrollY = 0;
    }

    // Clamp values if at the limits and record
    final int left = -maxOverScrollX;
    final int right = maxOverScrollX + scrollRangeX;
    final int top = -maxOverScrollY;
    final int bottom = maxOverScrollY + scrollRangeY;

    boolean clampedX = false;
    if (newScrollX > right) {
        newScrollX = right;
        clampedX = true;
    } else if (newScrollX < left) {
        newScrollX = left;
        clampedX = true;
    }

    boolean clampedY = false;
    if (newScrollY > bottom) {
        newScrollY = bottom;
        clampedY = true;
    } else if (newScrollY < top) {
        newScrollY = top;
        clampedY = true;
    }

    onOverScrolled(newScrollX, newScrollY, clampedX, clampedY);

    return clampedX || clampedY;
}

你可能感兴趣的:(View 的 OverScrollBy 方法)