package com.sxjs.common.widget.bottomnavigation.behaviour;
import android.content.Context;
import android.support.annotation.IntDef;
import android.support.design.widget.CoordinatorLayout;
import android.util.AttributeSet;
import android.view.View;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Class description
*
* @author ashokvarma
* @version 1.0
* @since 25 Mar 2016
*/
public abstract class VerticalScrollingBehavior<V extends View> extends CoordinatorLayout.Behavior<V> {
private int mTotalDyUnconsumed = -1;
private int mTotalDyConsumed = -1;
private int mTotalDy = -1;
@ScrollDirection
private int mScrollDirection = ScrollDirection.SCROLL_NONE;
@ScrollDirection
private int mPreScrollDirection = ScrollDirection.SCROLL_NONE;
@ScrollDirection
private int mConsumedScrollDirection = ScrollDirection.SCROLL_NONE;
public VerticalScrollingBehavior(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalScrollingBehavior() {
super();
}
@Retention(RetentionPolicy.SOURCE)
@IntDef({ScrollDirection.SCROLL_DIRECTION_UP, ScrollDirection.SCROLL_DIRECTION_DOWN})
public @interface ScrollDirection {
int SCROLL_DIRECTION_UP = 1;
int SCROLL_DIRECTION_DOWN = -1;
int SCROLL_NONE = 0;
}
/**
* @return Scroll direction: SCROLL_DIRECTION_UP, CROLL_DIRECTION_DOWN, SCROLL_NONE
*/
@ScrollDirection
public int getScrollDirection() {
return mScrollDirection;
}
/**
* @return ConsumedScroll direction: SCROLL_DIRECTION_UP, CROLL_DIRECTION_DOWN, SCROLL_NONE
*/
@ScrollDirection
public int getConsumedScrollDirection() {
return mConsumedScrollDirection;
}
/**
* @return PreScroll direction: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN, SCROLL_NONE
*/
@ScrollDirection
public int getPreScrollDirection() {
return mPreScrollDirection;
}
@Override
public boolean onStartNestedScroll(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
return (nestedScrollAxes & View.SCROLL_AXIS_VERTICAL) != 0;
}
// @Override
// public void onNestedScrollAccepted(CoordinatorLayout coordinatorLayout, V child, View directTargetChild, View target, int nestedScrollAxes) {
// super.onNestedScrollAccepted(coordinatorLayout, child, directTargetChild, target, nestedScrollAxes);
// }
//
// @Override
// public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target) {
// super.onStopNestedScroll(coordinatorLayout, child, target);
// }
@Override
public void onNestedScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed) {
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed);
if (dyUnconsumed > 0 && mTotalDyUnconsumed < 0) {
mTotalDyUnconsumed = 0;
mScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP;
onNestedVerticalScrollUnconsumed(coordinatorLayout, child, mScrollDirection, dyConsumed, mTotalDyUnconsumed);
} else if (dyUnconsumed < 0 && mTotalDyUnconsumed > 0) {
mTotalDyUnconsumed = 0;
mScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN;
onNestedVerticalScrollUnconsumed(coordinatorLayout, child, mScrollDirection, dyConsumed, mTotalDyUnconsumed);
}
mTotalDyUnconsumed += dyUnconsumed;
if (dyConsumed > 0 && mTotalDyConsumed < 0) {
mTotalDyConsumed = 0;
mConsumedScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP;
onNestedVerticalScrollConsumed(coordinatorLayout, child, mConsumedScrollDirection, dyConsumed, mTotalDyConsumed);
} else if (dyConsumed < 0 && mTotalDyConsumed > 0) {
mTotalDyConsumed = 0;
mConsumedScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN;
onNestedVerticalScrollConsumed(coordinatorLayout, child, mConsumedScrollDirection, dyConsumed, mTotalDyConsumed);
}
mTotalDyConsumed += dyConsumed;
}
@Override
public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed) {
super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
if (dy > 0 && mTotalDy < 0) {
mTotalDy = 0;
mPreScrollDirection = ScrollDirection.SCROLL_DIRECTION_UP;
onNestedVerticalPreScroll(coordinatorLayout, child, target, dx, dy, consumed, mPreScrollDirection);
} else if (dy < 0 && mTotalDy > 0) {
mTotalDy = 0;
mPreScrollDirection = ScrollDirection.SCROLL_DIRECTION_DOWN;
onNestedVerticalPreScroll(coordinatorLayout, child, target, dx, dy, consumed, mPreScrollDirection);
}
mTotalDy += dy;
}
@Override
public boolean onNestedFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed) {
super.onNestedFling(coordinatorLayout, child, target, velocityX, velocityY, consumed);
return onNestedDirectionFling(coordinatorLayout, child, target, velocityX, velocityY, consumed
, velocityY > 0 ? ScrollDirection.SCROLL_DIRECTION_UP : ScrollDirection.SCROLL_DIRECTION_DOWN);
}
/**
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
* associated with
* @param child the child view of the CoordinatorLayout this Behavior is associated with
* @param scrollDirection Direction of the scroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN
* @param currentOverScroll Unconsumed value, negative or positive based on the direction;
* @param totalScroll Cumulative value for current direction (Unconsumed)
*/
public abstract void onNestedVerticalScrollUnconsumed(CoordinatorLayout coordinatorLayout, V child, @ScrollDirection int scrollDirection, int currentOverScroll, int totalScroll);
/**
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
* associated with
* @param child the child view of the CoordinatorLayout this Behavior is associated with
* @param scrollDirection Direction of the scroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN
* @param currentOverScroll Unconsumed value, negative or positive based on the direction;
* @param totalConsumedScroll Cumulative value for current direction (Unconsumed)
*/
public abstract void onNestedVerticalScrollConsumed(CoordinatorLayout coordinatorLayout, V child, @ScrollDirection int scrollDirection, int currentOverScroll, int totalConsumedScroll);
/**
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
* associated with
* @param child the child view of the CoordinatorLayout this Behavior is associated with
* @param target the descendant view of the CoordinatorLayout performing the nested scroll
* @param dx the raw horizontal number of pixels that the user attempted to scroll
* @param dy the raw vertical number of pixels that the user attempted to scroll
* @param consumed out parameter. consumed[0] should be set to the distance of dx that
* was consumed, consumed[1] should be set to the distance of dy that
* was consumed
* @param scrollDirection Direction of the scroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN
*/
public abstract void onNestedVerticalPreScroll(CoordinatorLayout coordinatorLayout, V child, View target, int dx, int dy, int[] consumed, @ScrollDirection int scrollDirection);
/**
* @param coordinatorLayout the CoordinatorLayout parent of the view this Behavior is
* associated with
* @param child the child view of the CoordinatorLayout this Behavior is associated with
* @param target the descendant view of the CoordinatorLayout performing the nested scroll
* @param velocityX horizontal velocity of the attempted fling
* @param velocityY vertical velocity of the attempted fling
* @param consumed true if the nested child view consumed the fling
* @param scrollDirection Direction of the scroll: SCROLL_DIRECTION_UP, SCROLL_DIRECTION_DOWN
* @return true if the Behavior consumed the fling
*/
protected abstract boolean onNestedDirectionFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY, boolean consumed, @ScrollDirection int scrollDirection);
// @Override
// public boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, V child, View target, float velocityX, float velocityY) {
// return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY);
// }
//
// @Override
// public WindowInsetsCompat onApplyWindowInsets(CoordinatorLayout coordinatorLayout, V child, WindowInsetsCompat insets) {
//
// return super.onApplyWindowInsets(coordinatorLayout, child, insets);
// }
//
// @Override
// public Parcelable onSaveInstanceState(CoordinatorLayout parent, V child) {
// return super.onSaveInstanceState(parent, child);
// }
}