一直想写一个下拉刷新,一直没有一个好的想法,在git 中浏览了几款下啦刷新Demo,他们实现的方式也不一样,老一点的框架是自定义View 然后监听手势实现效果。新一点的是自定一ViewGroup 组建 然后结合 NestedScrollingParent, NestedScrollingChild两个属性,为了向下兼容 谷歌还提供了 NestedScrollingChildHelper ,NestedScrollingParentHelper 。
那么先来了解一下工程中所用到的接口和类
1 NestedScrollingChild
/** * Enable or disable nested scrolling for this view.
* * <p>If this property is set to true the view will be permitted to initiate nested
* scrolling operations with a compatible parent view in the current hierarchy. If this
* view does not implement nested scrolling this will have no effect. Disabling nested scrolling
* while a nested scroll is in progress has the effect of {@link #stopNestedScroll() stopping}
* the nested scroll.</p>
* * @param enabled true to enable nested scrolling, false to disable *
NestedScrollingParent
/** * React to a descendant view initiating a nestable scroll operation, claiming the
* nested scroll operation if appropriate.
* * <p>This method will be called in response to a descendant view invoking
* {@link ViewCompat#startNestedScroll(View, int)}. Each parent up the view hierarchy will be
* given an opportunity to respond and claim the nested scrolling operation by returning
* <code>true</code>.</p> *
* <p>This method may be overridden by ViewParent implementations to indicate when the view
* is willing to support a nested scrolling operation that is about to begin. If it returns
* true, this ViewParent will become the target view's nested scrolling parent for the duration
* of the scroll operation in progress. When the nested scroll is finished this ViewParent
* will receive a call to {@link #onStopNestedScroll(View)}.
* </p> * * @param child Direct child of this ViewParent containing target
* @param target View that initiated the nested scroll
* @param nestedScrollAxes Flags consisting of {@link ViewCompat#SCROLL_AXIS_HORIZONTAL}, * {@link ViewCompat#SCROLL_AXIS_VERTICAL} or both * @return true if this ViewParent accepts the nested scroll operation
注释很多,我们可以简单一点的认为 他们是为了实现 父View 于子View 之间的嵌套滑动。当然 前面也提到过 这个方法是 5.0 之后出来的 ,所以有 NestedScrollingChildHelper ,NestedScrollingParentHelper 。来帮助实现向下兼容。
NestedScrollingChild 子类实现的接口
public void setNestedScrollingEnabled(boolean enabled);
设置嵌套滑动是否可用
public boolean isNestedScrollingEnabled();
嵌套滑动是否可用
@param axes 表示方向 有一下两种值
* ViewCompat.SCROLL_AXIS_HORIZONTAL 横向哈东
* ViewCompat.SCROLL_AXIS_VERTICAL 纵向滑动
public boolean startNestedScroll(int axes);
滑动方向
public void stopNestedScroll();
停止滑动
public boolean hasNestedScrollingParent()
是否有父View 支持 嵌套滑动, 会一层层的网上寻找父View
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);
dxConsumed x轴上 被消费的距离
dyConsumed y轴上 被消费的距离
dxUnconsumed x轴上 未被消费的距离
dyUnconsumed y轴上 未被消费的距离
offsetInWindow view 的移动距离
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);
一般在滑动之前调用, 在ontouch 中计算出滑动距离, 然后 调用改 方法, 就给支持的嵌套的父View 处理滑动事件
dx x 轴上滑动的距离, 相对于上一次事件, 不是相对于 down事件的 那个距离
dy= y 轴上滑动的距离
consumed 一个数组, 可以传 一个空的 数组, 表示 x 方向 或 y 方向的事件 是否有被消费
offsetInWindow 支持嵌套滑动到额父View 消费 滑动事件后 导致 本 View 的移动距离
支持的嵌套的父View 是否处理了 滑动事件
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
x 轴上的滑动速度
velocityY y 轴上的滑动速度
consumed 是否被消费
public boolean dispatchNestedPreFling(float velocityX, float velocityY);
x 轴上的滑动速度
velocityY y 轴上的滑动速度
之后会整理逻辑然后将代码奉上。