一直想寫一個(gè)下拉刷新,一直沒有一個(gè)好的想法,在git 中瀏覽了幾款下啦刷新Demo,他們實(shí)現(xiàn)的方式也不一樣,老一點(diǎn)的框架是自定義View 然后監(jiān)聽手勢(shì)實(shí)現(xiàn)效果。新一點(diǎn)的是自定一ViewGroup 組建 然后結(jié)合 NestedScrollingParent, NestedScrollingChild兩個(gè)屬性,為了向下兼容 谷歌還提供了 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
注釋很多,我們可以簡(jiǎn)單一點(diǎn)的認(rèn)為 他們是為了實(shí)現(xiàn) 父View 于子View 之間的嵌套滑動(dòng)。當(dāng)然 前面也提到過 這個(gè)方法是 5.0 之后出來的 ,所以有 NestedScrollingChildHelper ,NestedScrollingParentHelper 。來幫助實(shí)現(xiàn)向下兼容。
NestedScrollingChild 子類實(shí)現(xiàn)的接口
public void setNestedScrollingEnabled(boolean enabled);
設(shè)置嵌套滑動(dòng)是否可用
public boolean isNestedScrollingEnabled();
嵌套滑動(dòng)是否可用
@param axes 表示方向 有一下兩種值
* ViewCompat.SCROLL_AXIS_HORIZONTAL 橫向哈東
* ViewCompat.SCROLL_AXIS_VERTICAL 縱向滑動(dòng)
public boolean startNestedScroll(int axes);
滑動(dòng)方向
public void stopNestedScroll();
停止滑動(dòng)
public boolean hasNestedScrollingParent()
是否有父View 支持 嵌套滑動(dòng), 會(huì)一層層的網(wǎng)上尋找父View
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow);
dxConsumed x軸上 被消費(fèi)的距離
dyConsumed y軸上 被消費(fèi)的距離
dxUnconsumed x軸上 未被消費(fèi)的距離
dyUnconsumed y軸上 未被消費(fèi)的距離
offsetInWindow view 的移動(dòng)距離
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow);
一般在滑動(dòng)之前調(diào)用, 在ontouch 中計(jì)算出滑動(dòng)距離, 然后 調(diào)用改 方法, 就給支持的嵌套的父View 處理滑動(dòng)事件
dx x 軸上滑動(dòng)的距離, 相對(duì)于上一次事件, 不是相對(duì)于 down事件的 那個(gè)距離
dy= y 軸上滑動(dòng)的距離
consumed 一個(gè)數(shù)組, 可以傳 一個(gè)空的 數(shù)組, 表示 x 方向 或 y 方向的事件 是否有被消費(fèi)
offsetInWindow 支持嵌套滑動(dòng)到額父View 消費(fèi) 滑動(dòng)事件后 導(dǎo)致 本 View 的移動(dòng)距離
支持的嵌套的父View 是否處理了 滑動(dòng)事件
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed);
x 軸上的滑動(dòng)速度
velocityY y 軸上的滑動(dòng)速度
consumed 是否被消費(fèi)
public boolean dispatchNestedPreFling(float velocityX, float velocityY);
x 軸上的滑動(dòng)速度
velocityY y 軸上的滑動(dòng)速度
之后會(huì)整理邏輯然后將代碼奉上。