package android.support.v4.view;
import android.view.View;
import android.view.ViewParent;
/**
* Helper class for implementing nested scrolling child views compatible with Android platform
* versions earlier than Android 5.0 Lollipop (API 21).
*
* <p>{@link android.view.View View} subclasses should instantiate a final instance of this
* class as a field at construction. For each <code>View</code> method that has a matching
* method signature in this class, delegate the operation to the helper instance in an overriden
* method implementation. This implements the standard framework policy for nested scrolling.</p>
*
* <p>Views invoking nested scrolling functionality should always do so from the relevant
* {@link ViewCompat}, {@link ViewGroupCompat} or {@link ViewParentCompat} compatibility
* shim static methods. This ensures interoperability with nested scrolling views on Android
* 5.0 Lollipop and newer.</p>
*/
/**
*用于实现与Android平台兼容的嵌套滚动子视图的helper类
*早于Android 5.0棒棒糖(API 21)的版本。
*
*<p>@link android.view.view view子类应实例化此的最后一个实例
*类作为构造字段。对于每个具有匹配的
*方法签名在此类中,将操作委托给重写中的帮助程序实例
*方法实现。这实现了嵌套滚动的标准框架策略。<p>
*
*<p>调用嵌套滚动功能的视图应该始终从相关的
*@link viewcompat,@link viewgroupcompat或@link viewparentcompat兼容性
*填隙静态方法。这确保了与Android上的嵌套滚动视图的互操作性。
*5.0棒棒糖和更新的。<p>
*/
public class NestedScrollingChildHelper {
private final View mView;
private ViewParent mNestedScrollingParent;
private boolean mIsNestedScrollingEnabled;
private int[] mTempNestedScrollConsumed;
/**
* Construct a new helper for a given view.
*/
public NestedScrollingChildHelper(View view) {
mView = view;
}
/**
* Enable nested scrolling.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @param enabled true to enable nested scrolling dispatch from this view, false otherwise
*/
/**
*启用嵌套滚动。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@param enabled true可从此视图启用嵌套滚动调度,否则为false
*/
public void setNestedScrollingEnabled(boolean enabled) {
if (mIsNestedScrollingEnabled) {
ViewCompat.stopNestedScroll(mView);
}
mIsNestedScrollingEnabled = enabled;
}
/**
* Check if nested scrolling is enabled for this view.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if nested scrolling is enabled for this view
*/
/**
*检查是否为此视图启用了嵌套滚动。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果此视图启用了嵌套滚动,则返回true
*/
public boolean isNestedScrollingEnabled() {
return mIsNestedScrollingEnabled;
}
/**
* Check if this view has a nested scrolling parent view currently receiving events for
* a nested scroll in progress.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if this view has a nested scrolling parent, false otherwise
*/
/**
*检查此视图是否有当前接收事件的嵌套滚动父视图
*正在进行嵌套滚动。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果此视图具有嵌套的滚动父级,则返回true,否则返回false。
*/
public boolean hasNestedScrollingParent() {
return mNestedScrollingParent != null;
}
/**
* Start a new nested scroll for this view.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @param axes Supported nested scroll axes.
* See {@link NestedScrollingChild#startNestedScroll(int)}.
* @return true if a cooperating parent view was found and nested scrolling started successfully
*/
/**
*为此视图启动新的嵌套滚动。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@参数轴支持嵌套滚动轴。
*请参见@link nestedcollingchild startnestedcoll(int)。
*@如果找到合作的父视图并成功启动嵌套滚动,则返回true
*/
public boolean startNestedScroll(int axes) {
if (hasNestedScrollingParent()) {
// Already in progress
return true;
}
if (isNestedScrollingEnabled()) {
ViewParent p = mView.getParent();
View child = mView;
while (p != null) {
if (ViewParentCompat.onStartNestedScroll(p, child, mView, axes)) {
mNestedScrollingParent = p;
ViewParentCompat.onNestedScrollAccepted(p, child, mView, axes);
return true;
}
if (p instanceof View) {
child = (View) p;
}
p = p.getParent();
}
}
return false;
}
/**
* Stop a nested scroll in progress.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*/
/**
*停止正在进行的嵌套滚动。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*/
public void stopNestedScroll() {
if (mNestedScrollingParent != null) {
ViewParentCompat.onStopNestedScroll(mNestedScrollingParent, mView);
mNestedScrollingParent = null;
}
}
/**
* Dispatch one step of a nested scrolling operation to the current nested scrolling parent.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if the parent consumed any of the nested scroll
*/
/**
*将嵌套滚动操作的一个步骤分派给当前嵌套滚动父级。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果父级使用了任何嵌套滚动,则返回true
*/
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed,
int dxUnconsumed, int dyUnconsumed, int[] offsetInWindow) {
if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
if (dxConsumed != 0 || dyConsumed != 0 || dxUnconsumed != 0 || dyUnconsumed != 0) {
int startX = 0;
int startY = 0;
if (offsetInWindow != null) {
mView.getLocationInWindow(offsetInWindow);
startX = offsetInWindow[0];
startY = offsetInWindow[1];
}
ViewParentCompat.onNestedScroll(mNestedScrollingParent, mView, dxConsumed,
dyConsumed, dxUnconsumed, dyUnconsumed);
if (offsetInWindow != null) {
mView.getLocationInWindow(offsetInWindow);
offsetInWindow[0] -= startX;
offsetInWindow[1] -= startY;
}
return true;
} else if (offsetInWindow != null) {
// No motion, no dispatch. Keep offsetInWindow up to date.
offsetInWindow[0] = 0;
offsetInWindow[1] = 0;
}
}
return false;
}
/**
* Dispatch one step of a nested pre-scrolling operation to the current nested scrolling parent.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if the parent consumed any of the nested scroll
*/
/**
*将嵌套的预滚动操作的一个步骤分派给当前嵌套的滚动父级。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果父级使用了任何嵌套滚动,则返回true
*/
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
if (dx != 0 || dy != 0) {
int startX = 0;
int startY = 0;
if (offsetInWindow != null) {
mView.getLocationInWindow(offsetInWindow);
startX = offsetInWindow[0];
startY = offsetInWindow[1];
}
if (consumed == null) {
if (mTempNestedScrollConsumed == null) {
mTempNestedScrollConsumed = new int[2];
}
consumed = mTempNestedScrollConsumed;
}
consumed[0] = 0;
consumed[1] = 0;
ViewParentCompat.onNestedPreScroll(mNestedScrollingParent, mView, dx, dy, consumed);
if (offsetInWindow != null) {
mView.getLocationInWindow(offsetInWindow);
offsetInWindow[0] -= startX;
offsetInWindow[1] -= startY;
}
return consumed[0] != 0 || consumed[1] != 0;
} else if (offsetInWindow != null) {
offsetInWindow[0] = 0;
offsetInWindow[1] = 0;
}
}
return false;
}
/**
* Dispatch a nested fling operation to the current nested scrolling parent.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if the parent consumed the nested fling
*/
/**
*将嵌套的抛出操作分派给当前嵌套的滚动父级。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果父级使用了嵌套的Fling,则返回true
*/
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
return ViewParentCompat.onNestedFling(mNestedScrollingParent, mView, velocityX,
velocityY, consumed);
}
return false;
}
/**
* Dispatch a nested pre-fling operation to the current nested scrolling parent.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @return true if the parent consumed the nested fling
*/
/**
*将嵌套的预抛出操作分派给当前嵌套的滚动父级。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@如果父级使用了嵌套的Fling,则返回true
*/
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
if (isNestedScrollingEnabled() && mNestedScrollingParent != null) {
return ViewParentCompat.onNestedPreFling(mNestedScrollingParent, mView, velocityX,
velocityY);
}
return false;
}
/**
* View subclasses should always call this method on their
* <code>NestedScrollingChildHelper</code> when detached from a window.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*/
/**
*视图子类应始终对其调用此方法
*从窗口分离时,<code>NestedScrollingChildHelper<code>
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*/
public void onDetachedFromWindow() {
ViewCompat.stopNestedScroll(mView);
}
/**
* Called when a nested scrolling child stops its current nested scroll operation.
*
* <p>This is a delegate method. Call it from your {@link android.view.View View} subclass
* method/{@link NestedScrollingChild} interface method with the same signature to implement
* the standard policy.</p>
*
* @param child Child view stopping its nested scroll. This may not be a direct child view.
*/
/**
*当嵌套滚动子级停止其当前嵌套滚动操作时调用。
*
*<p>这是委托方法。从你的@link android.view.view视图子类调用它
*方法/@link nestedcollingchild要实现的签名相同的接口方法
*标准政策。<p>
*
*@param child子视图停止其嵌套滚动。这可能不是直接的子视图。
*/
public void onStopNestedScroll(View child) {
ViewCompat.stopNestedScroll(mView);
}
}