From e284c666898f9e84f125f331fa9e56ab12b12f4b Mon Sep 17 00:00:00 2001 From: hzw <1993hzw@163.com> Date: Tue, 5 Mar 2019 15:12:51 +0800 Subject: [PATCH] optimize --- .../overscrolldemo/NestedScrollFragment.java | 2 +- .../VerticalRecyclerViewFragment.java | 21 +++- .../overscroll/BaseOverScrollBehavior.java | 116 +++++++++++------- .../cn/forward/overscroll/IOverScroll.java | 21 ++++ .../overscroll/IOverScrollCallback.java | 36 ++++-- .../OverScrollHorizontalBehavior.java | 4 + .../OverScrollVerticalBehavior.java | 4 + .../overscroll/SimpleOverScrollCallback.java | 25 ++-- .../OverScrollHorizontalRecyclerView.java | 108 +--------------- .../overscroll/view/OverScrollScrollView.java | 35 ++++-- .../view/OverScrollVerticalRecyclerView.java | 35 ++++-- 11 files changed, 197 insertions(+), 210 deletions(-) create mode 100644 overscroll/src/main/java/cn/forward/overscroll/IOverScroll.java diff --git a/app/src/main/java/cn/forward/overscrolldemo/NestedScrollFragment.java b/app/src/main/java/cn/forward/overscrolldemo/NestedScrollFragment.java index 2d2969c..8cefb81 100644 --- a/app/src/main/java/cn/forward/overscrolldemo/NestedScrollFragment.java +++ b/app/src/main/java/cn/forward/overscrolldemo/NestedScrollFragment.java @@ -54,7 +54,7 @@ public void onOffsetChanged(View child, int offset) { }); HorizontalRecyclerViewFragment.initHorizontal(view.findViewById(R.id.horizontal_view)); - +// VerticalRecyclerViewFragment.initVerticalOverScroll(view.findViewById(R.id.vertical_view)); return view; } diff --git a/app/src/main/java/cn/forward/overscrolldemo/VerticalRecyclerViewFragment.java b/app/src/main/java/cn/forward/overscrolldemo/VerticalRecyclerViewFragment.java index 85f633c..688370f 100644 --- a/app/src/main/java/cn/forward/overscrolldemo/VerticalRecyclerViewFragment.java +++ b/app/src/main/java/cn/forward/overscrolldemo/VerticalRecyclerViewFragment.java @@ -9,6 +9,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.Toast; import cn.forward.overscroll.IOffsetChangeListener; import cn.forward.overscroll.IOverScrollView; @@ -23,10 +24,12 @@ public class VerticalRecyclerViewFragment extends Fragment { @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - - View view = inflater.inflate(R.layout.layout_recyclerview_vertical, container, false); + initVerticalOverScroll(view); + return view; + } + public static void initVerticalOverScroll(View view) { final View iconHeaderView = view.findViewById(R.id.icon_header); final View iconFooterView = view.findViewById(R.id.icon_footer); @@ -62,7 +65,7 @@ public void onOffsetChanged(View child, int offset) { RecyclerView recyclerView = view.findViewById(R.id.overscroll_view); - recyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); + recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext(), LinearLayoutManager.VERTICAL, false)); recyclerView.setAdapter(new RecyclerView.Adapter() { @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -73,12 +76,19 @@ public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType } @Override - public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { + public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { TextView textView = holder.itemView.findViewById(R.id.text); - textView.setText("" + (1+position)); + textView.setText("" + (1 + position)); View container = holder.itemView.findViewById(R.id.container); container.setBackgroundColor(COLORS[position % COLORS.length]); + + container.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Toast.makeText(holder.itemView.getContext(), "" + (position + 1), Toast.LENGTH_SHORT).show(); + } + }); } @Override @@ -87,6 +97,5 @@ public int getItemCount() { } }); - return view; } } diff --git a/overscroll/src/main/java/cn/forward/overscroll/BaseOverScrollBehavior.java b/overscroll/src/main/java/cn/forward/overscroll/BaseOverScrollBehavior.java index 0482c46..e16a532 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/BaseOverScrollBehavior.java +++ b/overscroll/src/main/java/cn/forward/overscroll/BaseOverScrollBehavior.java @@ -7,6 +7,7 @@ import android.support.v4.math.MathUtils; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.animation.DecelerateInterpolator; import android.view.animation.Interpolator; @@ -17,7 +18,7 @@ * * @author ziwei huang */ -public abstract class BaseOverScrollBehavior extends CoordinatorLayout.Behavior { +public abstract class BaseOverScrollBehavior extends CoordinatorLayout.Behavior implements IOverScroll { private static final int MAX_BOUNCE_BACK_DURATION_MS = 300; private static final int MIN_BOUNCE_BACK_DURATION_MS = 150; @@ -43,8 +44,12 @@ public abstract boolean onStartNestedScroll(CoordinatorLayout parent, View child @Override public void onNestedScrollAccepted(@NonNull CoordinatorLayout coordinatorLayout, @NonNull View child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) { + if (child != target) { + return; + } + if (type == ViewCompat.TYPE_TOUCH) { - stopSpringBack(); + stopSpringBack(child); } if (type == ViewCompat.TYPE_TOUCH) { @@ -71,19 +76,23 @@ public abstract void onNestedPreScroll(CoordinatorLayout coordinatorLayout, View */ protected int onNestedPreScrollInner(CoordinatorLayout coordinatorLayout, View child, View target, int distance, int type) { + if (child != target) { + return 0; + } + IOverScrollCallback overscrollListener = (IOverScrollCallback) child; if (distance != 0) { int min, max; if (distance < 0) { // We're scrolling to end - if (!overscrollListener.canScroll(child, getOffset(child), mDirectionToEnd)) { + if (!overscrollListener.canScroll(this, child, mDirectionToEnd)) { return 0; } min = getOffset(child); max = 0; } else { // We're scrolling to start - if (!overscrollListener.canScroll(child, getOffset(child), mDirectionToStart)) { + if (!overscrollListener.canScroll(this, child, mDirectionToStart)) { return 0; } @@ -106,9 +115,13 @@ public abstract void onNestedScroll(CoordinatorLayout coordinatorLayout, View ch protected void onNestedScrollInner(CoordinatorLayout coordinatorLayout, View child, View target, int distanceConsumed, int distanceUnconsumed, int type) { + if (child != target) { + return; + } + IOverScrollCallback overscrollListener = (IOverScrollCallback) child; - if (distanceUnconsumed != 0) { + if (distanceUnconsumed != 0) { // fix nested scroll bugs coordinatorLayout.requestDisallowInterceptTouchEvent(true); } @@ -116,38 +129,39 @@ protected void onNestedScrollInner(CoordinatorLayout coordinatorLayout, View chi // If the scrolling view is scrolling to end but not consuming, it's probably be at // the top of it's content - if (!overscrollListener.canScroll(child, getOffset(child), mDirectionToEnd)) { + if (!overscrollListener.canScroll(this, child, mDirectionToEnd)) { return; } if (type == ViewCompat.TYPE_TOUCH) { scroll(child, distanceUnconsumed, 0, getMaxOffset(child)); } else { // fling - if ((mOverScroller.computeScrollOffset() - && Math.abs(mOverScroller.getCurrVelocity()) < Math.abs(overscrollListener.getMinFlingVelocity(child, getOffset(child), mDirectionToEnd))) // too slow - || getOffset(child) >= overscrollListener.getMaxFlingOffset(child, getOffset(child), mDirectionToEnd)) { // reach edge + if ((mOverScroller != null && mOverScroller.computeScrollOffset() + && Math.abs(mOverScroller.getCurrVelocity()) < Math.abs(overscrollListener.getMinFlingVelocity(this, child, mDirectionToEnd))) // too slow + || + getOffset(child) >= overscrollListener.getMaxFlingOffset(this, child, mDirectionToEnd)) { // reach edge ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); } else { - scroll(child, distanceUnconsumed, // slow down - getOffset(child), overscrollListener.getMaxFlingOffset(child, getOffset(child), mDirectionToEnd)); + scroll(child, distanceUnconsumed, + getOffset(child), overscrollListener.getMaxFlingOffset(this, child, mDirectionToEnd)); } } } else if (distanceUnconsumed > 0) { - if (!overscrollListener.canScroll(child, getOffset(child), mDirectionToStart)) { + if (!overscrollListener.canScroll(this, child, mDirectionToStart)) { return; } if (type == ViewCompat.TYPE_TOUCH) { scroll(child, distanceUnconsumed, getMinOffset(child), 0); } else { // fling - if ((mOverScroller.computeScrollOffset() - && Math.abs(mOverScroller.getCurrVelocity()) < overscrollListener.getMinFlingVelocity(child, getOffset(child), mDirectionToStart)) // too slow - || getOffset(child) <= overscrollListener.getMaxFlingOffset(child, getOffset(child), mDirectionToStart)) { // reach edge + if ((mOverScroller != null && mOverScroller.computeScrollOffset() + && Math.abs(mOverScroller.getCurrVelocity()) < overscrollListener.getMinFlingVelocity(this, child, mDirectionToStart)) // too slow + || getOffset(child) <= overscrollListener.getMaxFlingOffset(this, child, mDirectionToStart)) { // reach edge ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); } else { scroll(child, distanceUnconsumed, // slow down - overscrollListener.getMaxFlingOffset(child, getOffset(child), mDirectionToStart), getOffset(child)); + overscrollListener.getMaxFlingOffset(this, child, mDirectionToStart), getOffset(child)); } } } @@ -157,29 +171,44 @@ protected void onNestedScrollInner(CoordinatorLayout coordinatorLayout, View chi public abstract boolean onNestedPreFling(CoordinatorLayout coordinatorLayout, View child, View target, float velocityX, float velocityY); protected boolean onNestedPreFlingInner(CoordinatorLayout coordinatorLayout, View child, View target, float velocity) { - if (child == target) { - if (mOverScroller == null) { - mOverScroller = new OverScroller(coordinatorLayout.getContext()); - } - /* velocityX = 0, velocityY = velocity - or - velocityX = velocity, velocityY = 0 - */ - mOverScroller.fling(0, 0, 0, (int) velocity, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE); + if (child != target) { + return false; } + + if (getOffset(child) != 0) { // 越界后不能产生惯性滑动,否则造成越界过程中child内部同时也发生滑动 + // No fling can occur after crossing the boundary, otherwise the fling of the child will also occur during the crossing process. + ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + return true; // must true + } + + if (mOverScroller == null) { + mOverScroller = new OverScroller(coordinatorLayout.getContext()); + } + /* velocityX = 0, velocityY = velocity + or + velocityX = velocity, velocityY = 0 + */ + mOverScroller.fling(0, 0, 0, (int) velocity, 0, 0, Integer.MIN_VALUE, Integer.MAX_VALUE); + return false; } @Override public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, View target, int type) { + if (child != target) { + return; + } + if (type == ViewCompat.TYPE_TOUCH) { // touching if (getOffset(child) != 0) { // and out of bound - ViewCompat.stopNestedScroll(target, ViewCompat.TYPE_NON_TOUCH); + ViewCompat.stopNestedScroll(child, ViewCompat.TYPE_NON_TOUCH); springBack(child); } } else { - springBack(child); + if (getOffset(child) != 0) { + springBack(child); + } } } @@ -189,7 +218,7 @@ public void onStopNestedScroll(CoordinatorLayout coordinatorLayout, View child, private final int computerWithDampingFactor(View child, int distance) { IOverScrollCallback overscroll = (IOverScrollCallback) child; int direction = distance > 0 ? mDirectionToStart : mDirectionToEnd; - float factor = overscroll.getDampingFactor(child, getOffset(child), direction); + float factor = overscroll.getDampingFactor(this, child, direction); if (factor == 0) { factor = 1; } @@ -227,16 +256,20 @@ private int computerOffset(View child, int newOffset, int minOffset, int maxOffs return consumed; } - public void stopSpringBack() { - if (mSpringBackAnimator == null) { - return; + @Override + public void stopSpringBack(View child) { + if (mSpringBackAnimator != null) { + if (mSpringBackAnimator.isRunning()) { + mSpringBackAnimator.cancel(); + } } - if (mSpringBackAnimator.isRunning()) { - mSpringBackAnimator.cancel(); - } + IOverScrollCallback overScrollCallback = (IOverScrollCallback) child; + overScrollCallback.onStopSpringingBack(this, child); + } + @Override public void springBack(final View child) { IOverScrollCallback overScroll = (IOverScrollCallback) child; @@ -245,6 +278,10 @@ public void springBack(final View child) { return; } + if (overScroll.onSpringBack(this, child)) { + return; + } + if (mSpringBackAnimator == null) { mSpringBackAnimator = ValueAnimator.ofInt(); } @@ -257,7 +294,6 @@ public void springBack(final View child) { float bounceBackDuration = (Math.abs(startOffset) * 1f / getMaxOffset(child)) * MAX_BOUNCE_BACK_DURATION_MS; mSpringBackAnimator.setDuration(Math.max((int) bounceBackDuration, MIN_BOUNCE_BACK_DURATION_MS)); mSpringBackAnimator.setInterpolator(mSpringBackInterpolator); - overScroll.onSpringBack(child, startOffset, mSpringBackAnimator); mSpringBackAnimator.setIntValues(startOffset, 0); mSpringBackAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override @@ -269,18 +305,12 @@ public void onAnimationUpdate(ValueAnimator animation) { mSpringBackAnimator.start(); } + @Override public void setOffset(View child, int offset) { IOverScrollCallback overscrollListener = (IOverScrollCallback) child; updateOffset(child, offset); - overscrollListener.onOffsetChanged(child, getOffset(child)); + overscrollListener.onOffsetChanged(this, child, getOffset(child)); } protected abstract void updateOffset(View child, int offset); - - public abstract int getOffset(View child); - - public abstract int getMaxOffset(View child); - - public abstract int getMinOffset(View child); - } \ No newline at end of file diff --git a/overscroll/src/main/java/cn/forward/overscroll/IOverScroll.java b/overscroll/src/main/java/cn/forward/overscroll/IOverScroll.java new file mode 100644 index 0000000..8992a24 --- /dev/null +++ b/overscroll/src/main/java/cn/forward/overscroll/IOverScroll.java @@ -0,0 +1,21 @@ +package cn.forward.overscroll; + +import android.view.View; + +/** + * @author ziwei huang + */ +public interface IOverScroll { + + public void setOffset(View child, int offset); + + public int getOffset(View child); + + public int getMaxOffset(View child); + + public int getMinOffset(View child); + + public void stopSpringBack(View child); + + public void springBack(View child); +} diff --git a/overscroll/src/main/java/cn/forward/overscroll/IOverScrollCallback.java b/overscroll/src/main/java/cn/forward/overscroll/IOverScrollCallback.java index 8255071..b296604 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/IOverScrollCallback.java +++ b/overscroll/src/main/java/cn/forward/overscroll/IOverScrollCallback.java @@ -1,6 +1,5 @@ package cn.forward.overscroll; -import android.animation.Animator; import android.support.annotation.IntDef; import android.view.View; @@ -21,57 +20,68 @@ public interface IOverScrollCallback { public static final int DIRECTION_RIGHT = 1 << 3; /** + * @param overScroll * @param child the child view of the CoordinatorLayout this Behavior is associated with. 跟当前behavior绑定的CoordinatorLayout的子view - * @param offset offset the vertical offset for the child view, in px. 子View在垂直位置上的偏移值 * @param scrollDirection {@link #DIRECTION_UP} or {@link #DIRECTION_DOWN}. 过度滑动的方向 * @return true if the child view can scroll in the scroll direction. 返回true表示子view可以在相应的方向上过度滑动 */ - boolean canScroll(View child, int offset, @ScrollDirection int scrollDirection); + boolean canScroll(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection); /** * 最大的惯性滑动的偏移值 * + * @param overScroll * @param child - * @param offset * @param scrollDirection * @return max offsets when fling, in px */ - int getMaxFlingOffset(View child, int offset, @ScrollDirection int scrollDirection); + int getMaxFlingOffset(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection); /** * Damping factor, the larger the value, the harder it is to scroll * 阻尼因子,值越大则摩擦越大越难滑动 * + * @param overScroll * @param child - * @param offset * @param scrollDirection * @return Damping factor when scrolling, should be positive. Only take effect when you offset the child view away. */ - float getDampingFactor(View child, int offset, @ScrollDirection int scrollDirection); + float getDampingFactor(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection); /** * 产生惯性滑动的最小速度(取绝对值),小于该速度时会停止惯性滑动. * + * @param overScroll * @param child - * @param offset * @param scrollDirection * @return Minimum velocity (the absolute value) to occur a fling, in pixels per second. If the velocity is less than the min, the child view will stop the fling */ - int getMinFlingVelocity(View child, int offset, @ScrollDirection int scrollDirection); + int getMinFlingVelocity(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection); /** * callback when the child view's offset changed. * 子view发生偏移时回调 + * + * @param overScroll * @param child * @param offset */ - void onOffsetChanged(View child, int offset); + void onOffsetChanged(IOverScroll overScroll, View child, int offset); /** * callback before springing back + * + * @param overScroll + * @param child + * @return true if you have consumed the event, false if you haven't. The default implementation always returns false. + */ + boolean onSpringBack(IOverScroll overScroll, View child); + + /** + * callback before stop springing back + * + * @param overScroll * @param child - * @param offset - * @param animator the spring-back animation. You can change the animator before starting. */ - void onSpringBack(View child, int offset, Animator animator); + void onStopSpringingBack(IOverScroll overScroll, View child); } diff --git a/overscroll/src/main/java/cn/forward/overscroll/OverScrollHorizontalBehavior.java b/overscroll/src/main/java/cn/forward/overscroll/OverScrollHorizontalBehavior.java index ba2f68f..665c6a9 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/OverScrollHorizontalBehavior.java +++ b/overscroll/src/main/java/cn/forward/overscroll/OverScrollHorizontalBehavior.java @@ -23,6 +23,10 @@ public OverScrollHorizontalBehavior(Context context, AttributeSet attrs) { @Override public boolean onStartNestedScroll(CoordinatorLayout parent, View child, View directTargetChild, View target, int nestedScrollAxes, int type) { + if (child != target) { + return false; + } + return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_HORIZONTAL) != 0; } diff --git a/overscroll/src/main/java/cn/forward/overscroll/OverScrollVerticalBehavior.java b/overscroll/src/main/java/cn/forward/overscroll/OverScrollVerticalBehavior.java index 2120e51..b720283 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/OverScrollVerticalBehavior.java +++ b/overscroll/src/main/java/cn/forward/overscroll/OverScrollVerticalBehavior.java @@ -23,6 +23,10 @@ public OverScrollVerticalBehavior(Context context, AttributeSet attrs) { @Override public boolean onStartNestedScroll(CoordinatorLayout parent, View child, View directTargetChild, View target, int nestedScrollAxes, int type) { + if (child != target) { + return false; + } + return (nestedScrollAxes & ViewCompat.SCROLL_AXIS_VERTICAL) != 0; } diff --git a/overscroll/src/main/java/cn/forward/overscroll/SimpleOverScrollCallback.java b/overscroll/src/main/java/cn/forward/overscroll/SimpleOverScrollCallback.java index 66ec4f5..80dccbe 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/SimpleOverScrollCallback.java +++ b/overscroll/src/main/java/cn/forward/overscroll/SimpleOverScrollCallback.java @@ -1,30 +1,23 @@ package cn.forward.overscroll; -import android.animation.Animator; import android.view.View; import android.view.ViewConfiguration; -import android.view.animation.BounceInterpolator; -import android.view.animation.Interpolator; /** * @author ziwei huang */ public class SimpleOverScrollCallback implements IOverScrollCallback { - private static final int MAX_BOUNCE_BACK_DURATION_MS = 300; - private static final int MIN_BOUNCE_BACK_DURATION_MS = 150; - private int mMinFlingVelocity; - private Interpolator mInterpolator; @Override - public boolean canScroll(View child, int offset, @ScrollDirection int scrollDirection) { + public boolean canScroll(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection) { return true; } @Override - public int getMaxFlingOffset(View child, int offset, @ScrollDirection int scrollDirection) { + public int getMaxFlingOffset(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection) { if (scrollDirection == DIRECTION_DOWN || scrollDirection == DIRECTION_RIGHT) { return child.getHeight() / 3; } else { @@ -33,14 +26,14 @@ public int getMaxFlingOffset(View child, int offset, @ScrollDirection int scroll } @Override - public float getDampingFactor(View child, int offset, @ScrollDirection int scrollDirection) { - int absOffset = Math.abs(offset); + public float getDampingFactor(IOverScroll overScroll, View child, @ScrollDirection int scrollDirection) { + int absOffset = Math.abs(overScroll.getOffset(child)); float progress = absOffset * 1f / child.getHeight(); return 1 + 4 * progress; // factor = {1, 5} } @Override - public int getMinFlingVelocity(View child, int offset, int scrollDirection) { + public int getMinFlingVelocity(IOverScroll overScroll, View child, int scrollDirection) { if (mMinFlingVelocity <= 0) { mMinFlingVelocity = ViewConfiguration.get(child.getContext()).getScaledMinimumFlingVelocity() * 15; } @@ -48,12 +41,16 @@ public int getMinFlingVelocity(View child, int offset, int scrollDirection) { } @Override - public void onOffsetChanged(View child, int offset) { + public void onOffsetChanged(IOverScroll overScroll, View child, int offset) { } @Override - public void onSpringBack(View child, int offset, Animator animator) { + public boolean onSpringBack(IOverScroll overScroll, View child) { + return false; + } + @Override + public void onStopSpringingBack(IOverScroll overScroll, View child) { } } diff --git a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollHorizontalRecyclerView.java b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollHorizontalRecyclerView.java index 9cfb74a..30d6943 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollHorizontalRecyclerView.java +++ b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollHorizontalRecyclerView.java @@ -1,20 +1,10 @@ package cn.forward.overscroll.view; -import android.animation.Animator; import android.content.Context; import android.support.design.widget.CoordinatorLayout; -import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; -import android.view.View; -import java.util.ArrayList; -import java.util.List; - -import cn.forward.overscroll.IOffsetChangeListener; -import cn.forward.overscroll.IOverScrollCallback; -import cn.forward.overscroll.IOverScrollView; import cn.forward.overscroll.OverScrollHorizontalBehavior; -import cn.forward.overscroll.SimpleOverScrollCallback; /** * over scrolling horizontally for RecyclerView @@ -22,13 +12,7 @@ * @author ziwei huang */ @CoordinatorLayout.DefaultBehavior(OverScrollHorizontalBehavior.class) -public class OverScrollHorizontalRecyclerView extends RecyclerView implements IOverScrollCallback, IOverScrollView { - - private List mOffsetChangeListeners; - private IOverScrollCallback mDefaultOverCallback = new SimpleOverScrollCallback(); - private IOverScrollCallback mOverScrollCallback = mDefaultOverCallback; - - private Integer mOverScrollOffset; +public class OverScrollHorizontalRecyclerView extends OverScrollVerticalRecyclerView { public OverScrollHorizontalRecyclerView(Context context) { super(context); @@ -41,94 +25,4 @@ public OverScrollHorizontalRecyclerView(Context context, AttributeSet attrs) { public OverScrollHorizontalRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } - - public boolean canScroll(View child, int offset, int scrollDirection) { - if (mOverScrollCallback != null) { - return mOverScrollCallback.canScroll(child, offset, scrollDirection); - } - - return false; - } - - @Override - public int getMaxFlingOffset(View child, int offset, int scrollDirection) { - if (mOverScrollCallback != null) { - return mOverScrollCallback.getMaxFlingOffset(child, offset, scrollDirection); - } - - return 0; - } - - @Override - public float getDampingFactor(View child, int offset, int scrollDirection) { - if (mOverScrollCallback != null) { - return mOverScrollCallback.getDampingFactor(child, offset, scrollDirection); - } - - return 0; - } - - @Override - public int getMinFlingVelocity(View child, int offset, int scrollDirection) { - if (mOverScrollCallback != null) { - return mOverScrollCallback.getMinFlingVelocity(child, offset, scrollDirection); - } - - return 0; - } - - @Override - public void onOffsetChanged(View child, int offset) { - mOverScrollOffset = offset; - - if (mOverScrollCallback != null) { - mOverScrollCallback.onOffsetChanged(child, offset); - } - - for (int i = 0; i < mOffsetChangeListeners.size(); i++) { - mOffsetChangeListeners.get(i).onOffsetChanged(child, offset); - } - } - - @Override - public void onSpringBack(View child, int offset, Animator animator) { - if (mOverScrollCallback != null) { - mOverScrollCallback.onSpringBack(child, offset, animator); - } - } - - @Override - public void setOverScrollCallback(final IOverScrollCallback overScrollCallback) { - mOverScrollCallback = overScrollCallback; - } - - @Override - public IOverScrollCallback getOverScrollCallback() { - return mOverScrollCallback; - } - - public IOverScrollCallback getDefaultOverCallback() { - return mDefaultOverCallback; - } - - @Override - public void addOffsetChangeListener(final IOffsetChangeListener listener) { - if (mOffsetChangeListeners == null) { - mOffsetChangeListeners = new ArrayList<>(); - } - - if (listener != null && !mOffsetChangeListeners.contains(listener)) { - mOffsetChangeListeners.add(listener); - } - } - - @Override - public void removeOffsetChangeListener(IOffsetChangeListener listener) { - mOffsetChangeListeners.remove(listener); - } - - @Override - public int getOverScrollOffset() { - return mOverScrollOffset; - } } diff --git a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollScrollView.java b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollScrollView.java index 23421a5..54ca9c1 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollScrollView.java +++ b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollScrollView.java @@ -1,6 +1,5 @@ package cn.forward.overscroll.view; -import android.animation.Animator; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.v4.widget.NestedScrollView; @@ -11,6 +10,7 @@ import java.util.List; import cn.forward.overscroll.IOffsetChangeListener; +import cn.forward.overscroll.IOverScroll; import cn.forward.overscroll.IOverScrollCallback; import cn.forward.overscroll.IOverScrollView; import cn.forward.overscroll.OverScrollVerticalBehavior; @@ -40,47 +40,47 @@ public OverScrollScrollView(Context context, AttributeSet attrs, int defStyleAtt super(context, attrs, defStyleAttr); } - public boolean canScroll(View child, int offset, int scrollDirection) { + public boolean canScroll(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.canScroll(child, offset, scrollDirection); + return mOverScrollCallback.canScroll(overScroll, child, scrollDirection); } return false; } @Override - public int getMaxFlingOffset(View child, int offset, int scrollDirection) { + public int getMaxFlingOffset(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getMaxFlingOffset(child, offset, scrollDirection); + return mOverScrollCallback.getMaxFlingOffset(overScroll, child, scrollDirection); } return 0; } @Override - public float getDampingFactor(View child, int offset, int scrollDirection) { + public float getDampingFactor(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getDampingFactor(child, offset, scrollDirection); + return mOverScrollCallback.getDampingFactor(overScroll, child, scrollDirection); } return 0; } @Override - public int getMinFlingVelocity(View child, int offset, int scrollDirection) { + public int getMinFlingVelocity(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getMinFlingVelocity(child, offset, scrollDirection); + return mOverScrollCallback.getMinFlingVelocity(overScroll, child, scrollDirection); } return 0; } @Override - public void onOffsetChanged(View child, int offset) { + public void onOffsetChanged(IOverScroll overScroll, View child, int offset) { mOverScrollOffset = offset; if (mOverScrollCallback != null) { - mOverScrollCallback.onOffsetChanged(child, offset); + mOverScrollCallback.onOffsetChanged(overScroll, child, offset); } for (int i = 0; i < mOffsetChangeListeners.size(); i++) { @@ -89,9 +89,18 @@ public void onOffsetChanged(View child, int offset) { } @Override - public void onSpringBack(View child, int offset, Animator animator) { + public boolean onSpringBack(IOverScroll overScroll, View child) { if (mOverScrollCallback != null) { - mOverScrollCallback.onSpringBack(child, offset, animator); + return mOverScrollCallback.onSpringBack(overScroll, child); + } + + return false; + } + + @Override + public void onStopSpringingBack(IOverScroll overScroll, View child) { + if (mOverScrollCallback != null) { + mOverScrollCallback.onStopSpringingBack(overScroll, child); } } diff --git a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollVerticalRecyclerView.java b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollVerticalRecyclerView.java index f425e45..23b9712 100644 --- a/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollVerticalRecyclerView.java +++ b/overscroll/src/main/java/cn/forward/overscroll/view/OverScrollVerticalRecyclerView.java @@ -1,6 +1,5 @@ package cn.forward.overscroll.view; -import android.animation.Animator; import android.content.Context; import android.support.design.widget.CoordinatorLayout; import android.support.v7.widget.RecyclerView; @@ -11,6 +10,7 @@ import java.util.List; import cn.forward.overscroll.IOffsetChangeListener; +import cn.forward.overscroll.IOverScroll; import cn.forward.overscroll.IOverScrollCallback; import cn.forward.overscroll.IOverScrollView; import cn.forward.overscroll.OverScrollVerticalBehavior; @@ -42,47 +42,47 @@ public OverScrollVerticalRecyclerView(Context context, AttributeSet attrs, int d super(context, attrs, defStyleAttr); } - public boolean canScroll(View child, int offset, int scrollDirection) { + public boolean canScroll(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.canScroll(child, offset, scrollDirection); + return mOverScrollCallback.canScroll(overScroll, child, scrollDirection); } return false; } @Override - public int getMaxFlingOffset(View child, int offset, int scrollDirection) { + public int getMaxFlingOffset(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getMaxFlingOffset(child, offset, scrollDirection); + return mOverScrollCallback.getMaxFlingOffset(overScroll, child, scrollDirection); } return 0; } @Override - public float getDampingFactor(View child, int offset, int scrollDirection) { + public float getDampingFactor(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getDampingFactor(child, offset, scrollDirection); + return mOverScrollCallback.getDampingFactor(overScroll, child, scrollDirection); } return 0; } @Override - public int getMinFlingVelocity(View child, int offset, int scrollDirection) { + public int getMinFlingVelocity(IOverScroll overScroll, View child, int scrollDirection) { if (mOverScrollCallback != null) { - return mOverScrollCallback.getMinFlingVelocity(child, offset, scrollDirection); + return mOverScrollCallback.getMinFlingVelocity(overScroll, child, scrollDirection); } return 0; } @Override - public void onOffsetChanged(View child, int offset) { + public void onOffsetChanged(IOverScroll overScroll, View child, int offset) { mOverScrollOffset = offset; if (mOverScrollCallback != null) { - mOverScrollCallback.onOffsetChanged(child, offset); + mOverScrollCallback.onOffsetChanged(overScroll, child, offset); } for (int i = 0; i < mOffsetChangeListeners.size(); i++) { @@ -91,9 +91,18 @@ public void onOffsetChanged(View child, int offset) { } @Override - public void onSpringBack(View child, int offset, Animator animator) { + public boolean onSpringBack(IOverScroll overScroll, View child) { if (mOverScrollCallback != null) { - mOverScrollCallback.onSpringBack(child, offset, animator); + return mOverScrollCallback.onSpringBack(overScroll, child); + } + + return false; + } + + @Override + public void onStopSpringingBack(IOverScroll overScroll, View child) { + if (mOverScrollCallback != null) { + mOverScrollCallback.onStopSpringingBack(overScroll, child); } }