diff --git a/demo/res/layout/activity_demo.xml b/demo/res/layout/activity_demo.xml index 440245b9..732f7107 100644 --- a/demo/res/layout/activity_demo.xml +++ b/demo/res/layout/activity_demo.xml @@ -14,8 +14,7 @@ sothree:umanoShadowHeight="4dp" sothree:umanoParallaxOffset="100dp" sothree:umanoDragView="@+id/dragView" - sothree:umanoOverlay="true" - sothree:umanoScrollableView="@+id/list"> + sothree:umanoOverlay="true"> - diff --git a/library/src/com/sothree/slidinguppanel/ScrollableViewHelper.java b/library/src/com/sothree/slidinguppanel/ScrollableViewHelper.java deleted file mode 100644 index 224ac30d..00000000 --- a/library/src/com/sothree/slidinguppanel/ScrollableViewHelper.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.sothree.slidinguppanel; - -import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.widget.ListView; -import android.widget.ScrollView; - -/** - * Helper class for determining the current scroll positions for scrollable views. Currently works - * for ListView, ScrollView & RecyclerView, but the library users can override it to add support - * for other views. - */ -public class ScrollableViewHelper { - /** - * Returns the current scroll position of the scrollable view. If this method returns zero or - * less, it means at the scrollable view is in a position such as the panel should handle - * scrolling. If the method returns anything above zero, then the panel will let the scrollable - * view handle the scrolling - * - * @param scrollableView the scrollable view - * @param isSlidingUp whether or not the panel is sliding up or down - * @return the scroll position - */ - public int getScrollableViewScrollPosition(View scrollableView, boolean isSlidingUp) { - if (scrollableView == null) return 0; - if (scrollableView instanceof ScrollView) { - if (isSlidingUp) { - return scrollableView.getScrollY(); - } else { - ScrollView sv = ((ScrollView) scrollableView); - View child = sv.getChildAt(0); - return (child.getBottom() - (sv.getHeight() + sv.getScrollY())); - } - } else if (scrollableView instanceof ListView && ((ListView) scrollableView).getChildCount() > 0) { - ListView lv = ((ListView) scrollableView); - if (lv.getAdapter() == null) return 0; - if (isSlidingUp) { - View firstChild = lv.getChildAt(0); - // Approximate the scroll position based on the top child and the first visible item - return lv.getFirstVisiblePosition() * firstChild.getHeight() - firstChild.getTop(); - } else { - View lastChild = lv.getChildAt(lv.getChildCount() - 1); - // Approximate the scroll position based on the bottom child and the last visible item - return (lv.getAdapter().getCount() - lv.getLastVisiblePosition() - 1) * lastChild.getHeight() + lastChild.getBottom() - lv.getBottom(); - } - } else if (scrollableView instanceof RecyclerView && ((RecyclerView) scrollableView).getChildCount() > 0) { - RecyclerView rv = ((RecyclerView) scrollableView); - RecyclerView.LayoutManager lm = rv.getLayoutManager(); - if (rv.getAdapter() == null) return 0; - if (isSlidingUp) { - View firstChild = rv.getChildAt(0); - // Approximate the scroll position based on the top child and the first visible item - return rv.getChildLayoutPosition(firstChild) * lm.getDecoratedMeasuredHeight(firstChild) - lm.getDecoratedTop(firstChild); - } else { - View lastChild = rv.getChildAt(rv.getChildCount() - 1); - // Approximate the scroll position based on the bottom child and the last visible item - return (rv.getAdapter().getItemCount() - 1) * lm.getDecoratedMeasuredHeight(lastChild) + lm.getDecoratedBottom(lastChild) - rv.getBottom(); - } - } else { - return 0; - } - } -} diff --git a/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java b/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java index 5329d5b5..62054b96 100644 --- a/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java +++ b/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java @@ -141,13 +141,6 @@ public class SlidingUpPanelLayout extends ViewGroup { */ private int mDragViewResId = -1; - /** - * If provided, the panel will transfer the scroll from this view to itself when needed. - */ - private View mScrollableView; - private int mScrollableViewResId; - private ScrollableViewHelper mScrollableViewHelper = new ScrollableViewHelper(); - /** * The child view that can slide, if any. */ @@ -327,7 +320,6 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { mCoveredFadeColor = ta.getColor(R.styleable.SlidingUpPanelLayout_umanoFadeColor, DEFAULT_FADE_COLOR); mDragViewResId = ta.getResourceId(R.styleable.SlidingUpPanelLayout_umanoDragView, -1); - mScrollableViewResId = ta.getResourceId(R.styleable.SlidingUpPanelLayout_umanoScrollableView, -1); mOverlayContent = ta.getBoolean(R.styleable.SlidingUpPanelLayout_umanoOverlay, DEFAULT_OVERLAY_FLAG); mClipPanel = ta.getBoolean(R.styleable.SlidingUpPanelLayout_umanoClipPanel, DEFAULT_CLIP_PANEL_FLAG); @@ -383,9 +375,6 @@ protected void onFinishInflate() { if (mDragViewResId != -1) { setDragView(findViewById(mDragViewResId)); } - if (mScrollableViewResId != -1) { - setScrollableView(findViewById(mScrollableViewResId)); - } } public void setGravity(int gravity) { @@ -570,24 +559,6 @@ public void setDragView(int dragViewResId) { setDragView(findViewById(dragViewResId)); } - /** - * Set the scrollable child of the sliding layout. If set, scrolling will be transfered between - * the panel and the view when necessary - * - * @param scrollableView The scrollable view - */ - public void setScrollableView(View scrollableView) { - mScrollableView = scrollableView; - } - - /** - * Sets the current scrollable view helper. See ScrollableViewHelper description for details. - * @param helper - */ - public void setScrollableViewHelper(ScrollableViewHelper helper) { - mScrollableViewHelper = helper; - } - /** * Set an anchor point where the panel can stop during sliding * @@ -974,9 +945,8 @@ public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { float dy = y - mPrevMotionY; mPrevMotionY = y; - // If the scroll view isn't under the touch, pass the - // event along to the dragView. - if (!isViewUnder(mScrollableView, (int) mInitialMotionX, (int) mInitialMotionY)) { + // If the slidable view isn't under the touch, pass the event. + if (!isViewUnder(mSlideableView, (int) mInitialMotionX, (int) mInitialMotionY)) { return super.dispatchTouchEvent(ev); } @@ -984,7 +954,7 @@ public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { if (dy * (mIsSlidingUp ? 1 : -1) > 0) { // Collapsing // Is the child less than fully scrolled? // Then let the child handle it. - if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mIsSlidingUp) > 0) { + if (canScrollVertically(mSlideableView, mInitialMotionX, mInitialMotionY, mIsSlidingUp ? -1 : 1)) { mIsScrollableViewHandlingTouch = true; return super.dispatchTouchEvent(ev); } @@ -1035,6 +1005,24 @@ public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { return super.dispatchTouchEvent(ev); } + private boolean canScrollVertically(View view, float x, float y, int direction) { + if (view instanceof ViewGroup) { + ViewGroup vg = (ViewGroup) view; + for (int i = 0; i < vg.getChildCount(); i++) { + View child = vg.getChildAt(i); + int childLeft = child.getLeft(); + int childTop = child.getTop(); + int childRight = child.getRight(); + int childBottom = child.getBottom(); + boolean intersects = x > childLeft && x < childRight && y > childTop && y < childBottom; + if (intersects && canScrollVertically(child, x - childLeft, y - childTop, direction)) { + return true; + } + } + } + return ViewCompat.canScrollVertically(view, direction); + } + private boolean isViewUnder(View view, int x, int y) { if (view == null) return false; int[] viewLocation = new int[2];