From 4f2f5ee31a785853dc5a9ecc3847eaa54e54b86a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Roy=C3=A9?= Date: Tue, 9 May 2017 15:55:40 +0200 Subject: [PATCH 1/4] Fixed Bug: SlidingUpPanelLayout ignores setPanelState(), as long as animated settling is in progress. --- .../com/sothree/slidinguppanel/SlidingUpPanelLayout.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java index 57f89a12..16f15dc5 100644 --- a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java +++ b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java @@ -17,6 +17,7 @@ import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; +import android.util.Log; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; @@ -1089,6 +1090,13 @@ public PanelState getPanelState() { * @param state - new panel state */ public void setPanelState(PanelState state) { + + // Abort any running animation, to allow state change + if(mDragHelper.getViewDragState() == ViewDragHelper.STATE_SETTLING){ + Log.d(TAG, "View is settling. Aborting animation."); + mDragHelper.abort(); + } + if (state == null || state == PanelState.DRAGGING) { throw new IllegalArgumentException("Panel state cannot be null or DRAGGING."); } @@ -1219,6 +1227,7 @@ boolean smoothSlideTo(float slideOffset, int velocity) { } int panelTop = computePanelTopPosition(slideOffset); + if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), panelTop)) { setAllChildrenVisible(); ViewCompat.postInvalidateOnAnimation(this); From 3a3e5ac7c60ba16c6af3e5d14c6d2f0793da5066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Roy=C3=A9?= Date: Fri, 12 May 2017 15:49:47 +0200 Subject: [PATCH 2/4] New Horizontal Sliding functionality with Gravity.LEFT and Gravity.RIGHT --- .../slidinguppanel/SlidingUpPanelLayout.java | 487 +++++++++++++----- .../slidinguppanel/ViewDragHelper.java | 6 + library/src/main/res/drawable/left_shadow.xml | 8 + .../src/main/res/drawable/right_shadow.xml | 8 + 4 files changed, 390 insertions(+), 119 deletions(-) create mode 100644 library/src/main/res/drawable/left_shadow.xml create mode 100644 library/src/main/res/drawable/right_shadow.xml diff --git a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java index 16f15dc5..7474884d 100644 --- a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java +++ b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java @@ -8,12 +8,8 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.drawable.Drawable; -import android.os.Build; import android.os.Bundle; -import android.os.Parcel; import android.os.Parcelable; -import android.support.annotation.NonNull; -import android.support.v4.app.BundleCompat; import android.support.v4.view.MotionEventCompat; import android.support.v4.view.ViewCompat; import android.util.AttributeSet; @@ -38,7 +34,7 @@ public class SlidingUpPanelLayout extends ViewGroup { /** * Default peeking out panel height */ - private static final int DEFAULT_PANEL_HEIGHT = 68; // dp; + private static final int DEFAULT_PANEL_SIZE = 68; // dp; /** * Default anchor point height @@ -50,10 +46,14 @@ public class SlidingUpPanelLayout extends ViewGroup { */ private static PanelState DEFAULT_SLIDE_STATE = PanelState.COLLAPSED; + private static SlidingDirection DEFAULT_SLIDING_DIRECTION = SlidingDirection.UP; + + + /** * Default height of the shadow above the peeking out panel */ - private static final int DEFAULT_SHADOW_HEIGHT = 4; // dp; + private static final int DEFAULT_SHADOW_SIZE = 4; // dp; /** * If no fade color is given by default it will fade to 80% gray. @@ -111,7 +111,7 @@ public class SlidingUpPanelLayout extends ViewGroup { /** * The size of the overhang in pixels. */ - private int mPanelHeight = -1; + private int mPaneSize = -1; /** * The size of the shadow in pixels. @@ -123,10 +123,7 @@ public class SlidingUpPanelLayout extends ViewGroup { */ private int mParallaxOffset = -1; - /** - * True if the collapsed panel should be dragged up. - */ - private boolean mIsSlidingUp; + private boolean mIsSlidingVertically = true; /** * Panel overlays the windows instead of putting it underneath it. @@ -180,6 +177,18 @@ public enum PanelState { private PanelState mSlideState = DEFAULT_SLIDE_STATE; + /** + * Sliding direction, based on gravity + */ + public enum SlidingDirection { + UP, + DOWN, + LEFT, + RIGHT + } + + private SlidingDirection mSlidingDirection = DEFAULT_SLIDING_DIRECTION; + /** * If the current slide state is DRAGGING, this will store the last non dragging state */ @@ -212,7 +221,7 @@ public enum PanelState { */ private boolean mIsTouchEnabled; - private float mPrevMotionY; + private float mPrevMotionLocation; private float mInitialMotionX; private float mInitialMotionY; private boolean mIsScrollableViewHandlingTouch = false; @@ -296,7 +305,7 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingUpPanelLayout); if (ta != null) { - mPanelHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoPanelHeight, -1); + mPaneSize = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoPanelHeight, -1); mShadowHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoShadowHeight, -1); mParallaxOffset = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoParallaxOffset, -1); @@ -323,21 +332,32 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { } final float density = context.getResources().getDisplayMetrics().density; - if (mPanelHeight == -1) { - mPanelHeight = (int) (DEFAULT_PANEL_HEIGHT * density + 0.5f); + if (mPaneSize == -1) { + mPaneSize = (int) (DEFAULT_PANEL_SIZE * density + 0.5f); } if (mShadowHeight == -1) { - mShadowHeight = (int) (DEFAULT_SHADOW_HEIGHT * density + 0.5f); + mShadowHeight = (int) (DEFAULT_SHADOW_SIZE * density + 0.5f); } if (mParallaxOffset == -1) { mParallaxOffset = (int) (DEFAULT_PARALLAX_OFFSET * density); } // If the shadow height is zero, don't show the shadow if (mShadowHeight > 0) { - if (mIsSlidingUp) { - mShadowDrawable = getResources().getDrawable(R.drawable.above_shadow); - } else { - mShadowDrawable = getResources().getDrawable(R.drawable.below_shadow); + switch (mSlidingDirection) { + case UP: + mShadowDrawable = getResources().getDrawable(R.drawable.above_shadow); + break; + case DOWN: + mShadowDrawable = getResources().getDrawable(R.drawable.below_shadow); + break; + case LEFT: + mShadowDrawable = getResources().getDrawable(R.drawable.left_shadow); + break; + case RIGHT: + mShadowDrawable = getResources().getDrawable(R.drawable.right_shadow); + break; + default: + mShadowDrawable = null; } } else { mShadowDrawable = null; @@ -366,10 +386,28 @@ protected void onFinishInflate() { } public void setGravity(int gravity) { - if (gravity != Gravity.TOP && gravity != Gravity.BOTTOM) { - throw new IllegalArgumentException("gravity must be set to either top or bottom"); + if (gravity != Gravity.TOP && gravity != Gravity.BOTTOM + && gravity != Gravity.LEFT && gravity != Gravity.RIGHT) { + throw new IllegalArgumentException("gravity must be set to either top, bottom, left or right"); + } + switch (gravity) { + case Gravity.BOTTOM: + mSlidingDirection = SlidingDirection.UP; + mIsSlidingVertically = true; + break; + case Gravity.TOP: + mSlidingDirection = SlidingDirection.DOWN; + mIsSlidingVertically = true; + break; + case Gravity.LEFT: + mSlidingDirection = SlidingDirection.RIGHT; + mIsSlidingVertically = false; + break; + case Gravity.RIGHT: + mSlidingDirection = SlidingDirection.LEFT; + mIsSlidingVertically = false; + break; } - mIsSlidingUp = gravity == Gravity.BOTTOM; if (!mFirstLayout) { requestLayout(); } @@ -416,7 +454,7 @@ public void setPanelHeight(int val) { return; } - mPanelHeight = val; + mPaneSize = val; if (!mFirstLayout) { requestLayout(); } @@ -455,7 +493,7 @@ public void setShadowHeight(int val) { * @return The current collapsed panel height */ public int getPanelHeight() { - return mPanelHeight; + return mPaneSize; } /** @@ -464,7 +502,9 @@ public int getPanelHeight() { public int getCurrentParallaxOffset() { // Clamp slide offset at zero for parallax computation; int offset = (int) (mParallaxOffset * Math.max(mSlideOffset, 0)); - return mIsSlidingUp ? -offset : offset; + + return mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT + ? -offset : offset; } /** @@ -770,42 +810,82 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = layoutWidth; if (child == mMainView) { if (!mOverlayContent && mSlideState != PanelState.HIDDEN) { - height -= mPanelHeight; + if(mIsSlidingVertically){ + height -= mPaneSize; + } else { + width -= mPaneSize; + } } - width -= lp.leftMargin + lp.rightMargin; + if (mIsSlidingVertically){ + width -= lp.leftMargin + lp.rightMargin; + } else { + height -= lp.topMargin + lp.bottomMargin; + } } else if (child == mSlideableView) { // The slideable view should be aware of its top margin. // See https://github.com/umano/AndroidSlidingUpPanel/issues/412. - height -= lp.topMargin; + if(mIsSlidingVertically){ + height -= lp.topMargin; + } else { + width -= lp.leftMargin; + } } int childWidthSpec; - if (lp.width == LayoutParams.WRAP_CONTENT) { - childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); - } else if (lp.width == LayoutParams.MATCH_PARENT) { - childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); - } else { - childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); - } - int childHeightSpec; - if (lp.height == LayoutParams.WRAP_CONTENT) { - childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); - } else { - // Modify the height based on the weight. - if (lp.weight > 0 && lp.weight < 1) { - height = (int) (height * lp.weight); - } else if (lp.height != LayoutParams.MATCH_PARENT) { - height = lp.height; + + if(mIsSlidingVertically){ + if (lp.width == LayoutParams.WRAP_CONTENT) { + childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); + } else if (lp.width == LayoutParams.MATCH_PARENT) { + childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); + } else { + childWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY); + } + + if (lp.height == LayoutParams.WRAP_CONTENT) { + childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); + } else { + // Modify the height based on the weight. + if (lp.weight > 0 && lp.weight < 1) { + height = (int) (height * lp.weight); + } else if (lp.height != LayoutParams.MATCH_PARENT) { + height = lp.height; + } + childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + } + } else { // Horizontally + if (lp.height == LayoutParams.WRAP_CONTENT) { + childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST); + } else if (lp.height == LayoutParams.MATCH_PARENT) { + childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); + } else { + childHeightSpec = MeasureSpec.makeMeasureSpec(lp.height, MeasureSpec.EXACTLY); + } + + if (lp.width == LayoutParams.WRAP_CONTENT) { + childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); + } else { + // Modify the width based on the weight. + if (lp.weight > 0 && lp.weight < 1) { + width = (int) (width * lp.weight); + } else if (lp.width != LayoutParams.MATCH_PARENT) { + width = lp.width; + } + childWidthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY); } - childHeightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); } + child.measure(childWidthSpec, childHeightSpec); if (child == mSlideableView) { - mSlideRange = mSlideableView.getMeasuredHeight() - mPanelHeight; + if(mIsSlidingVertically){ + mSlideRange = mSlideableView.getMeasuredHeight() - mPaneSize; + } else { + mSlideRange = mSlideableView.getMeasuredWidth() - mPaneSize; + } } } @@ -828,8 +908,14 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { mSlideOffset = mAnchorPoint; break; case HIDDEN: - int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); - mSlideOffset = computeSlideOffset(newTop); + if(mIsSlidingVertically){ + int newTop = computePanelTopPosition(0.0f) + (mSlidingDirection == SlidingDirection.UP ? +mPaneSize : -mPaneSize); + mSlideOffset = computeSlideOffset(newTop); + } else { + int newLeft = computePanelLeftPosition(0.0f) + (mSlidingDirection == SlidingDirection.LEFT ? +mPaneSize : -mPaneSize); + mSlideOffset = computeSlideOffset(newLeft); + } + break; default: mSlideOffset = 0.f; @@ -846,23 +932,46 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { continue; } - final int childHeight = child.getMeasuredHeight(); - int childTop = paddingTop; + if (mIsSlidingVertically) { - if (child == mSlideableView) { - childTop = computePanelTopPosition(mSlideOffset); - } + int childTop = paddingTop; + if (child == mSlideableView) { + childTop = computePanelTopPosition(mSlideOffset); + } + + if (mSlidingDirection == SlidingDirection.DOWN) { + if (child == mMainView && !mOverlayContent) { + childTop = computePanelTopPosition(mSlideOffset) + mSlideableView.getMeasuredHeight(); + } + } + + final int childHeight = child.getMeasuredHeight(); + final int childBottom = childTop + childHeight; + final int childLeft = paddingLeft + lp.leftMargin; + final int childRight = childLeft + child.getMeasuredWidth(); + + child.layout(childLeft, childTop, childRight, childBottom); + } else { + int childLeft = paddingLeft; + + if (child == mSlideableView) { + childLeft = computePanelLeftPosition(mSlideOffset); + } - if (!mIsSlidingUp) { - if (child == mMainView && !mOverlayContent) { - childTop = computePanelTopPosition(mSlideOffset) + mSlideableView.getMeasuredHeight(); + if (mSlidingDirection == SlidingDirection.RIGHT) { + if (child == mMainView && !mOverlayContent) { + childLeft = computePanelLeftPosition(mSlideOffset) + mSlideableView.getMeasuredWidth(); + } } + + final int childWidth = child.getMeasuredWidth(); + final int childRight = childLeft + childWidth; + final int childTop = paddingTop + lp.topMargin; + final int childBottom = childTop + child.getMeasuredHeight(); + + child.layout(childLeft, childTop, childRight, childBottom); } - final int childBottom = childTop + childHeight; - final int childLeft = paddingLeft + lp.leftMargin; - final int childRight = childLeft + child.getMeasuredWidth(); - child.layout(childLeft, childTop, childRight, childBottom); } if (mFirstLayout) { @@ -965,14 +1074,19 @@ public boolean dispatchTouchEvent(MotionEvent ev) { return super.dispatchTouchEvent(ev); } - final float y = ev.getY(); + final float location; + if (mIsSlidingVertically) { + location = ev.getY(); + } else { + location = ev.getX(); + } if (action == MotionEvent.ACTION_DOWN) { mIsScrollableViewHandlingTouch = false; - mPrevMotionY = y; + mPrevMotionLocation = location; } else if (action == MotionEvent.ACTION_MOVE) { - float dy = y - mPrevMotionY; - mPrevMotionY = y; + float deltaLocation = location - mPrevMotionLocation; + mPrevMotionLocation = location; // If the scroll view isn't under the touch, pass the // event along to the dragView. @@ -981,10 +1095,17 @@ public boolean dispatchTouchEvent(MotionEvent ev) { } // Which direction (up or down) is the drag moving? - if (dy * (mIsSlidingUp ? 1 : -1) > 0) { // Collapsing + int factor = 0; + if(mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT){ + factor = 1; + } else { + factor = -1; + } + if (deltaLocation * factor > 0) { // Collapsing // Is the child less than fully scrolled? // Then let the child handle it. - if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mIsSlidingUp) > 0) { + // TODO: Does the ScrollableViewHandler need to know about horizontal sliding? + if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mSlidingDirection == SlidingDirection.UP) > 0) { mIsScrollableViewHandlingTouch = true; return super.dispatchTouchEvent(ev); } @@ -1006,7 +1127,7 @@ public boolean dispatchTouchEvent(MotionEvent ev) { mIsScrollableViewHandlingTouch = false; return this.onTouchEvent(ev); - } else if (dy * (mIsSlidingUp ? 1 : -1) < 0) { // Expanding + } else if (deltaLocation * factor < 0) { // Expanding // Is the panel less than fully expanded? // Then we'll handle the drag here. if (mSlideOffset < 1.0f) { @@ -1056,23 +1177,40 @@ private int computePanelTopPosition(float slideOffset) { int slidingViewHeight = mSlideableView != null ? mSlideableView.getMeasuredHeight() : 0; int slidePixelOffset = (int) (slideOffset * mSlideRange); // Compute the top of the panel if its collapsed - return mIsSlidingUp - ? getMeasuredHeight() - getPaddingBottom() - mPanelHeight - slidePixelOffset - : getPaddingTop() - slidingViewHeight + mPanelHeight + slidePixelOffset; + return mSlidingDirection == SlidingDirection.UP + ? getMeasuredHeight() - getPaddingBottom() - mPaneSize - slidePixelOffset + : getPaddingTop() - slidingViewHeight + mPaneSize + slidePixelOffset; + } + + /* + * Computes the left position of the panel based on the slide offset. + */ + private int computePanelLeftPosition(float slideOffset) { + int slidingViewWidth = mSlideableView != null ? mSlideableView.getMeasuredWidth() : 0; + int slidePixelOffset = (int) (slideOffset * mSlideRange); + // Compute the top of the panel if its collapsed + return mSlidingDirection == SlidingDirection.LEFT + ? getMeasuredWidth() - getPaddingRight() - mPaneSize - slidePixelOffset + : getPaddingLeft() - slidingViewWidth + mPaneSize + slidePixelOffset; } /* * Computes the slide offset based on the top position of the panel */ - private float computeSlideOffset(int topPosition) { + private float computeSlideOffset(int topOrLeftPosition) { // Compute the panel top position if the panel is collapsed (offset 0) - final int topBoundCollapsed = computePanelTopPosition(0); + final int topOrLeftBoundCollapsed; + if(mIsSlidingVertically){ + topOrLeftBoundCollapsed = computePanelTopPosition(0); + } else { + topOrLeftBoundCollapsed = computePanelLeftPosition(0); + } // Determine the new slide offset based on the collapsed top position and the new required // top position - return (mIsSlidingUp - ? (float) (topBoundCollapsed - topPosition) / mSlideRange - : (float) (topPosition - topBoundCollapsed) / mSlideRange); + return (mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT + ? (float) (topOrLeftBoundCollapsed - topOrLeftPosition) / mSlideRange + : (float) (topOrLeftPosition - topOrLeftBoundCollapsed) / mSlideRange); } /** @@ -1123,8 +1261,14 @@ public void setPanelState(PanelState state) { smoothSlideTo(1.0f, 0); break; case HIDDEN: - int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); - smoothSlideTo(computeSlideOffset(newTop), 0); + if (mIsSlidingVertically) { + int newTop = computePanelTopPosition(0.0f) + (mSlidingDirection == SlidingDirection.UP ? +mPaneSize : -mPaneSize); + smoothSlideTo(computeSlideOffset(newTop), 0); + } else { + int newTop = computePanelLeftPosition(0.0f) + (mSlidingDirection == SlidingDirection.LEFT ? +mPaneSize : -mPaneSize); + smoothSlideTo(computeSlideOffset(newTop), 0); + } + break; } } @@ -1144,35 +1288,51 @@ private void setPanelStateInternal(PanelState state) { private void applyParallaxForCurrentSlideOffset() { if (mParallaxOffset > 0) { int mainViewOffset = getCurrentParallaxOffset(); - ViewCompat.setTranslationY(mMainView, mainViewOffset); + if (mIsSlidingVertically){ + ViewCompat.setTranslationY(mMainView, mainViewOffset); + } else { + ViewCompat.setTranslationX(mMainView, mainViewOffset); + } } } - private void onPanelDragged(int newTop) { + private void onPanelDragged(int newTopOrLeft) { if (mSlideState != PanelState.DRAGGING) { mLastNotDraggingSlideState = mSlideState; } setPanelStateInternal(PanelState.DRAGGING); // Recompute the slide offset based on the new top position - mSlideOffset = computeSlideOffset(newTop); + mSlideOffset = computeSlideOffset(newTopOrLeft); applyParallaxForCurrentSlideOffset(); // Dispatch the slide event dispatchOnPanelSlide(mSlideableView); // If the slide offset is negative, and overlay is not on, we need to increase the // height of the main content LayoutParams lp = (LayoutParams) mMainView.getLayoutParams(); - int defaultHeight = getHeight() - getPaddingBottom() - getPaddingTop() - mPanelHeight; + int defaultHeight = getHeight() - getPaddingBottom() - getPaddingTop() - mPaneSize; + int defaultWidth = getWidth() - getPaddingRight() - getPaddingLeft() - mPaneSize; if (mSlideOffset <= 0 && !mOverlayContent) { // expand the main view - lp.height = mIsSlidingUp ? (newTop - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTop); - if (lp.height == defaultHeight) { - lp.height = LayoutParams.MATCH_PARENT; + if(mIsSlidingVertically){ + lp.height = mSlidingDirection == SlidingDirection.UP ? (newTopOrLeft - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTopOrLeft); + if (lp.height == defaultHeight) { + lp.height = LayoutParams.MATCH_PARENT; + } + } else { + lp.width = mSlidingDirection == SlidingDirection.LEFT ? (newTopOrLeft - getPaddingRight()) : (getWidth() - getPaddingRight() - mSlideableView.getMeasuredWidth() - newTopOrLeft); + if (lp.width == defaultWidth) { + lp.width = LayoutParams.MATCH_PARENT; + } } + mMainView.requestLayout(); - } else if (lp.height != LayoutParams.MATCH_PARENT && !mOverlayContent) { + } else if (mIsSlidingVertically && (lp.height != LayoutParams.MATCH_PARENT && !mOverlayContent)) { lp.height = LayoutParams.MATCH_PARENT; mMainView.requestLayout(); + } else if (!mIsSlidingVertically && (lp.width != LayoutParams.MATCH_PARENT && !mOverlayContent)) { + lp.width = LayoutParams.MATCH_PARENT; + mMainView.requestLayout(); } } @@ -1186,10 +1346,18 @@ protected boolean drawChild(Canvas canvas, View child, long drawingTime) { // Unless the panel is set to overlay content canvas.getClipBounds(mTmpRect); if (!mOverlayContent) { - if (mIsSlidingUp) { - mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop()); - } else { - mTmpRect.top = Math.max(mTmpRect.top, mSlideableView.getBottom()); + switch (mSlidingDirection){ + case UP: + mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop()); + break; + case DOWN: + mTmpRect.top = Math.max(mTmpRect.top, mSlideableView.getBottom()); + break; + case LEFT: + mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft()); + break; + case RIGHT: + mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight()); } } if (mClipPanel) { @@ -1226,9 +1394,16 @@ boolean smoothSlideTo(float slideOffset, int velocity) { return false; } - int panelTop = computePanelTopPosition(slideOffset); + boolean success; + if(mIsSlidingVertically){ + int panelTop = computePanelTopPosition(slideOffset); + success = mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), panelTop); + } else { + int panelLeft = computePanelLeftPosition(slideOffset); + success = mDragHelper.smoothSlideViewTo(mSlideableView, panelLeft, mSlideableView.getTop()); + } - if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), panelTop)) { + if (success) { setAllChildrenVisible(); ViewCompat.postInvalidateOnAnimation(this); return true; @@ -1254,17 +1429,31 @@ public void draw(Canvas c) { // draw the shadow if (mShadowDrawable != null && mSlideableView != null) { - final int right = mSlideableView.getRight(); - final int top; - final int bottom; - if (mIsSlidingUp) { - top = mSlideableView.getTop() - mShadowHeight; - bottom = mSlideableView.getTop(); + final int top, bottom, left, right; + if(mIsSlidingVertically){ + if (mSlidingDirection == SlidingDirection.UP) { + top = mSlideableView.getTop() - mShadowHeight; + bottom = mSlideableView.getTop(); + } else { + top = mSlideableView.getBottom(); + bottom = mSlideableView.getBottom() + mShadowHeight; + } + + right = mSlideableView.getRight(); + left = mSlideableView.getLeft(); } else { - top = mSlideableView.getBottom(); - bottom = mSlideableView.getBottom() + mShadowHeight; + if (mSlidingDirection == SlidingDirection.LEFT) { + left = mSlideableView.getLeft() - mShadowHeight; + right = mSlideableView.getLeft(); + } else { + left = mSlideableView.getRight(); + right = mSlideableView.getRight() + mShadowHeight; + } + + top = mSlideableView.getTop(); + bottom = mSlideableView.getBottom(); } - final int left = mSlideableView.getLeft(); + mShadowDrawable.setBounds(left, top, right, bottom); mShadowDrawable.draw(c); } @@ -1357,7 +1546,11 @@ public boolean tryCaptureView(View child, int pointerId) { @Override public void onViewDragStateChanged(int state) { if (mDragHelper.getViewDragState() == ViewDragHelper.STATE_IDLE) { - mSlideOffset = computeSlideOffset(mSlideableView.getTop()); + if(mIsSlidingVertically){ + mSlideOffset = computeSlideOffset(mSlideableView.getTop()); + } else { + mSlideOffset = computeSlideOffset(mSlideableView.getLeft()); + } applyParallaxForCurrentSlideOffset(); if (mSlideOffset == 1) { @@ -1382,7 +1575,11 @@ public void onViewCaptured(View capturedChild, int activePointerId) { @Override public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) { - onPanelDragged(top); + if(mIsSlidingVertically){ + onPanelDragged(top); + } else { + onPanelDragged(left); + } invalidate(); } @@ -1391,48 +1588,100 @@ public void onViewReleased(View releasedChild, float xvel, float yvel) { int target = 0; // direction is always positive if we are sliding in the expanded direction - float direction = mIsSlidingUp ? -yvel : yvel; + float direction; + if (mIsSlidingVertically){ + direction = mSlidingDirection == SlidingDirection.UP ? -yvel : yvel; + } else { + direction = mSlidingDirection == SlidingDirection.LEFT ? -xvel : xvel; + } if (direction > 0 && mSlideOffset <= mAnchorPoint) { // swipe up -> expand and stop at anchor point - target = computePanelTopPosition(mAnchorPoint); + if (mIsSlidingVertically) target = computePanelTopPosition(mAnchorPoint); + else target = computePanelLeftPosition(mAnchorPoint); } else if (direction > 0 && mSlideOffset > mAnchorPoint) { // swipe up past anchor -> expand - target = computePanelTopPosition(1.0f); + if (mIsSlidingVertically) target = computePanelTopPosition(1.0f); + else target = computePanelLeftPosition(1.0f); } else if (direction < 0 && mSlideOffset >= mAnchorPoint) { // swipe down -> collapse and stop at anchor point - target = computePanelTopPosition(mAnchorPoint); + if (mIsSlidingVertically) target = computePanelTopPosition(mAnchorPoint); + else target = computePanelLeftPosition(mAnchorPoint); } else if (direction < 0 && mSlideOffset < mAnchorPoint) { // swipe down past anchor -> collapse - target = computePanelTopPosition(0.0f); + if(mIsSlidingVertically) target = computePanelTopPosition(0.0f); + else target = computePanelLeftPosition(0.0f); } else if (mSlideOffset >= (1.f + mAnchorPoint) / 2) { // zero velocity, and far enough from anchor point => expand to the top - target = computePanelTopPosition(1.0f); + if(mIsSlidingVertically) target = computePanelTopPosition(1.0f); + else target = computePanelLeftPosition(1.0f); } else if (mSlideOffset >= mAnchorPoint / 2) { // zero velocity, and close enough to anchor point => go to anchor - target = computePanelTopPosition(mAnchorPoint); + if(mIsSlidingVertically) target = computePanelTopPosition(mAnchorPoint); + else target = computePanelLeftPosition(mAnchorPoint); } else { // settle at the bottom - target = computePanelTopPosition(0.0f); + if (mIsSlidingVertically) target = computePanelTopPosition(0.0f); + else target = computePanelLeftPosition(0.0f); } - mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), target); + if(mIsSlidingVertically){ + mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), target); + } else { + mDragHelper.settleCapturedViewAt(target, releasedChild.getTop()); + } invalidate(); } @Override public int getViewVerticalDragRange(View child) { - return mSlideRange; + if(mIsSlidingVertically){ // Vertical + return mSlideRange; + } else { // Horizontal + return super.getViewVerticalDragRange(child); + } + } + + @Override + public int getViewHorizontalDragRange(View child) { + if(!mIsSlidingVertically){ // Horizontal + return mSlideRange; + } else { // Vertical + return super.getViewHorizontalDragRange(child); + } } @Override public int clampViewPositionVertical(View child, int top, int dy) { - final int collapsedTop = computePanelTopPosition(0.f); - final int expandedTop = computePanelTopPosition(1.0f); - if (mIsSlidingUp) { - return Math.min(Math.max(top, expandedTop), collapsedTop); - } else { - return Math.min(Math.max(top, collapsedTop), expandedTop); + // The ViewDragHelper does not know, which scrolling direction is allowed and which not. + // Therefore only clamp view position, if vertical scrolling is enabled, here. + if(mIsSlidingVertically){ + final int collapsedTop = computePanelTopPosition(0.f); + final int expandedTop = computePanelTopPosition(1.0f); + if (mSlidingDirection == SlidingDirection.UP) { + return Math.min(Math.max(top, expandedTop), collapsedTop); + } else { + return Math.min(Math.max(top, collapsedTop), expandedTop); + } + } else { // Horizontally + return super.clampViewPositionVertical(child, top, dy); + } + } + + @Override + public int clampViewPositionHorizontal(View child, int left, int dx) { + // The ViewDragHelper does not know, which scrolling direction is allowed and which not. + // Therefore only clamp view position, if horizontal scrolling is enabled, here. + if(!mIsSlidingVertically) {// Horizontally + final int collapsedLeft = computePanelLeftPosition(0.f); + final int expandedLeft = computePanelLeftPosition(1.0f); + if (mSlidingDirection == SlidingDirection.LEFT) { + return Math.min(Math.max(left, expandedLeft), collapsedLeft); + } else { + return Math.min(Math.max(left, collapsedLeft), expandedLeft); + } + } else { // Vertically + return super.clampViewPositionHorizontal(child, left, dx); } } } diff --git a/library/src/main/java/com/sothree/slidinguppanel/ViewDragHelper.java b/library/src/main/java/com/sothree/slidinguppanel/ViewDragHelper.java index 58a4e82a..e8cae58b 100644 --- a/library/src/main/java/com/sothree/slidinguppanel/ViewDragHelper.java +++ b/library/src/main/java/com/sothree/slidinguppanel/ViewDragHelper.java @@ -760,6 +760,12 @@ public boolean continueSettling(boolean deferCallbacks) { return true; } + if(!keepGoing && dx != 0) { //fix #525 (Copy for horizontal sliding + //Invalid drag state + mCapturedView.setLeft(0); + return true; + } + if (dx != 0) { mCapturedView.offsetLeftAndRight(dx); } diff --git a/library/src/main/res/drawable/left_shadow.xml b/library/src/main/res/drawable/left_shadow.xml new file mode 100644 index 00000000..e08e48cf --- /dev/null +++ b/library/src/main/res/drawable/left_shadow.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file diff --git a/library/src/main/res/drawable/right_shadow.xml b/library/src/main/res/drawable/right_shadow.xml new file mode 100644 index 00000000..a473b631 --- /dev/null +++ b/library/src/main/res/drawable/right_shadow.xml @@ -0,0 +1,8 @@ + + + + + \ No newline at end of file From 9d6bb4700b5459f3069bd4f954b4c113fafb695b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Roy=C3=A9?= Date: Fri, 12 May 2017 16:15:00 +0200 Subject: [PATCH 3/4] Fixed wrong shadow directions. --- library/src/main/res/drawable/left_shadow.xml | 2 +- library/src/main/res/drawable/right_shadow.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/library/src/main/res/drawable/left_shadow.xml b/library/src/main/res/drawable/left_shadow.xml index e08e48cf..a473b631 100644 --- a/library/src/main/res/drawable/left_shadow.xml +++ b/library/src/main/res/drawable/left_shadow.xml @@ -3,6 +3,6 @@ + android:angle="180" > \ No newline at end of file diff --git a/library/src/main/res/drawable/right_shadow.xml b/library/src/main/res/drawable/right_shadow.xml index a473b631..e08e48cf 100644 --- a/library/src/main/res/drawable/right_shadow.xml +++ b/library/src/main/res/drawable/right_shadow.xml @@ -3,6 +3,6 @@ + android:angle="0" > \ No newline at end of file From 475090ac602434c3ad5a7088087e1b722ff8ec77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Roy=C3=A9?= Date: Wed, 17 May 2017 13:59:20 +0200 Subject: [PATCH 4/4] Removed SlidingDirection enum and replaced with actual gravity. --- .../slidinguppanel/SlidingUpPanelLayout.java | 96 ++++++++----------- 1 file changed, 41 insertions(+), 55 deletions(-) diff --git a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java index 7474884d..b8b67289 100644 --- a/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java +++ b/library/src/main/java/com/sothree/slidinguppanel/SlidingUpPanelLayout.java @@ -41,14 +41,16 @@ public class SlidingUpPanelLayout extends ViewGroup { */ private static final float DEFAULT_ANCHOR_POINT = 1.0f; // In relative % + /** + * Default gravity + */ + private static final int DEFAULT_GRAVITY = Gravity.BOTTOM; + /** * Default initial state for the component */ private static PanelState DEFAULT_SLIDE_STATE = PanelState.COLLAPSED; - private static SlidingDirection DEFAULT_SLIDING_DIRECTION = SlidingDirection.UP; - - /** * Default height of the shadow above the peeking out panel @@ -178,16 +180,9 @@ public enum PanelState { private PanelState mSlideState = DEFAULT_SLIDE_STATE; /** - * Sliding direction, based on gravity + * */ - public enum SlidingDirection { - UP, - DOWN, - LEFT, - RIGHT - } - - private SlidingDirection mSlidingDirection = DEFAULT_SLIDING_DIRECTION; + private int mGravity = DEFAULT_GRAVITY; /** * If the current slide state is DRAGGING, this will store the last non dragging state @@ -343,17 +338,17 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { } // If the shadow height is zero, don't show the shadow if (mShadowHeight > 0) { - switch (mSlidingDirection) { - case UP: + switch (mGravity) { + case Gravity.BOTTOM: mShadowDrawable = getResources().getDrawable(R.drawable.above_shadow); break; - case DOWN: + case Gravity.TOP: mShadowDrawable = getResources().getDrawable(R.drawable.below_shadow); break; - case LEFT: + case Gravity.RIGHT: mShadowDrawable = getResources().getDrawable(R.drawable.left_shadow); break; - case RIGHT: + case Gravity.LEFT: mShadowDrawable = getResources().getDrawable(R.drawable.right_shadow); break; default: @@ -390,21 +385,13 @@ public void setGravity(int gravity) { && gravity != Gravity.LEFT && gravity != Gravity.RIGHT) { throw new IllegalArgumentException("gravity must be set to either top, bottom, left or right"); } + + mGravity = gravity; switch (gravity) { - case Gravity.BOTTOM: - mSlidingDirection = SlidingDirection.UP; - mIsSlidingVertically = true; - break; - case Gravity.TOP: - mSlidingDirection = SlidingDirection.DOWN; + case Gravity.BOTTOM: case Gravity.TOP: mIsSlidingVertically = true; break; - case Gravity.LEFT: - mSlidingDirection = SlidingDirection.RIGHT; - mIsSlidingVertically = false; - break; - case Gravity.RIGHT: - mSlidingDirection = SlidingDirection.LEFT; + case Gravity.LEFT: case Gravity.RIGHT: mIsSlidingVertically = false; break; } @@ -503,8 +490,7 @@ public int getCurrentParallaxOffset() { // Clamp slide offset at zero for parallax computation; int offset = (int) (mParallaxOffset * Math.max(mSlideOffset, 0)); - return mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT - ? -offset : offset; + return mGravity == Gravity.BOTTOM || mGravity == Gravity.RIGHT ? -offset : offset; } /** @@ -909,10 +895,10 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { break; case HIDDEN: if(mIsSlidingVertically){ - int newTop = computePanelTopPosition(0.0f) + (mSlidingDirection == SlidingDirection.UP ? +mPaneSize : -mPaneSize); + int newTop = computePanelTopPosition(0.0f) + (mGravity == Gravity.BOTTOM ? +mPaneSize : -mPaneSize); mSlideOffset = computeSlideOffset(newTop); } else { - int newLeft = computePanelLeftPosition(0.0f) + (mSlidingDirection == SlidingDirection.LEFT ? +mPaneSize : -mPaneSize); + int newLeft = computePanelLeftPosition(0.0f) + (mGravity == Gravity.RIGHT ? +mPaneSize : -mPaneSize); mSlideOffset = computeSlideOffset(newLeft); } @@ -939,7 +925,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { childTop = computePanelTopPosition(mSlideOffset); } - if (mSlidingDirection == SlidingDirection.DOWN) { + if (mGravity == Gravity.TOP) { if (child == mMainView && !mOverlayContent) { childTop = computePanelTopPosition(mSlideOffset) + mSlideableView.getMeasuredHeight(); } @@ -958,7 +944,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) { childLeft = computePanelLeftPosition(mSlideOffset); } - if (mSlidingDirection == SlidingDirection.RIGHT) { + if (mGravity == Gravity.LEFT) { if (child == mMainView && !mOverlayContent) { childLeft = computePanelLeftPosition(mSlideOffset) + mSlideableView.getMeasuredWidth(); } @@ -1096,7 +1082,7 @@ public boolean dispatchTouchEvent(MotionEvent ev) { // Which direction (up or down) is the drag moving? int factor = 0; - if(mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT){ + if(mGravity == Gravity.BOTTOM || mGravity == Gravity.RIGHT){ factor = 1; } else { factor = -1; @@ -1105,7 +1091,7 @@ public boolean dispatchTouchEvent(MotionEvent ev) { // Is the child less than fully scrolled? // Then let the child handle it. // TODO: Does the ScrollableViewHandler need to know about horizontal sliding? - if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mSlidingDirection == SlidingDirection.UP) > 0) { + if (mScrollableViewHelper.getScrollableViewScrollPosition(mScrollableView, mGravity == Gravity.BOTTOM) > 0) { mIsScrollableViewHandlingTouch = true; return super.dispatchTouchEvent(ev); } @@ -1177,7 +1163,7 @@ private int computePanelTopPosition(float slideOffset) { int slidingViewHeight = mSlideableView != null ? mSlideableView.getMeasuredHeight() : 0; int slidePixelOffset = (int) (slideOffset * mSlideRange); // Compute the top of the panel if its collapsed - return mSlidingDirection == SlidingDirection.UP + return mGravity == Gravity.BOTTOM ? getMeasuredHeight() - getPaddingBottom() - mPaneSize - slidePixelOffset : getPaddingTop() - slidingViewHeight + mPaneSize + slidePixelOffset; } @@ -1189,7 +1175,7 @@ private int computePanelLeftPosition(float slideOffset) { int slidingViewWidth = mSlideableView != null ? mSlideableView.getMeasuredWidth() : 0; int slidePixelOffset = (int) (slideOffset * mSlideRange); // Compute the top of the panel if its collapsed - return mSlidingDirection == SlidingDirection.LEFT + return mGravity == Gravity.RIGHT ? getMeasuredWidth() - getPaddingRight() - mPaneSize - slidePixelOffset : getPaddingLeft() - slidingViewWidth + mPaneSize + slidePixelOffset; } @@ -1208,7 +1194,7 @@ private float computeSlideOffset(int topOrLeftPosition) { // Determine the new slide offset based on the collapsed top position and the new required // top position - return (mSlidingDirection == SlidingDirection.UP || mSlidingDirection == SlidingDirection.LEFT + return (mGravity == Gravity.BOTTOM || mGravity == Gravity.RIGHT ? (float) (topOrLeftBoundCollapsed - topOrLeftPosition) / mSlideRange : (float) (topOrLeftPosition - topOrLeftBoundCollapsed) / mSlideRange); } @@ -1262,10 +1248,10 @@ public void setPanelState(PanelState state) { break; case HIDDEN: if (mIsSlidingVertically) { - int newTop = computePanelTopPosition(0.0f) + (mSlidingDirection == SlidingDirection.UP ? +mPaneSize : -mPaneSize); + int newTop = computePanelTopPosition(0.0f) + (mGravity == Gravity.BOTTOM ? +mPaneSize : -mPaneSize); smoothSlideTo(computeSlideOffset(newTop), 0); } else { - int newTop = computePanelLeftPosition(0.0f) + (mSlidingDirection == SlidingDirection.LEFT ? +mPaneSize : -mPaneSize); + int newTop = computePanelLeftPosition(0.0f) + (mGravity == Gravity.RIGHT ? +mPaneSize : -mPaneSize); smoothSlideTo(computeSlideOffset(newTop), 0); } @@ -1315,12 +1301,12 @@ private void onPanelDragged(int newTopOrLeft) { if (mSlideOffset <= 0 && !mOverlayContent) { // expand the main view if(mIsSlidingVertically){ - lp.height = mSlidingDirection == SlidingDirection.UP ? (newTopOrLeft - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTopOrLeft); + lp.height = mGravity == Gravity.BOTTOM ? (newTopOrLeft - getPaddingBottom()) : (getHeight() - getPaddingBottom() - mSlideableView.getMeasuredHeight() - newTopOrLeft); if (lp.height == defaultHeight) { lp.height = LayoutParams.MATCH_PARENT; } } else { - lp.width = mSlidingDirection == SlidingDirection.LEFT ? (newTopOrLeft - getPaddingRight()) : (getWidth() - getPaddingRight() - mSlideableView.getMeasuredWidth() - newTopOrLeft); + lp.width = mGravity == Gravity.RIGHT ? (newTopOrLeft - getPaddingRight()) : (getWidth() - getPaddingRight() - mSlideableView.getMeasuredWidth() - newTopOrLeft); if (lp.width == defaultWidth) { lp.width = LayoutParams.MATCH_PARENT; } @@ -1346,17 +1332,17 @@ protected boolean drawChild(Canvas canvas, View child, long drawingTime) { // Unless the panel is set to overlay content canvas.getClipBounds(mTmpRect); if (!mOverlayContent) { - switch (mSlidingDirection){ - case UP: + switch (mGravity){ + case Gravity.BOTTOM: mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop()); break; - case DOWN: + case Gravity.TOP: mTmpRect.top = Math.max(mTmpRect.top, mSlideableView.getBottom()); break; - case LEFT: + case Gravity.RIGHT: mTmpRect.right = Math.min(mTmpRect.right, mSlideableView.getLeft()); break; - case RIGHT: + case Gravity.LEFT: mTmpRect.left = Math.max(mTmpRect.left, mSlideableView.getRight()); } } @@ -1431,7 +1417,7 @@ public void draw(Canvas c) { if (mShadowDrawable != null && mSlideableView != null) { final int top, bottom, left, right; if(mIsSlidingVertically){ - if (mSlidingDirection == SlidingDirection.UP) { + if (mGravity == Gravity.BOTTOM) { top = mSlideableView.getTop() - mShadowHeight; bottom = mSlideableView.getTop(); } else { @@ -1442,7 +1428,7 @@ public void draw(Canvas c) { right = mSlideableView.getRight(); left = mSlideableView.getLeft(); } else { - if (mSlidingDirection == SlidingDirection.LEFT) { + if (mGravity == Gravity.RIGHT) { left = mSlideableView.getLeft() - mShadowHeight; right = mSlideableView.getLeft(); } else { @@ -1590,9 +1576,9 @@ public void onViewReleased(View releasedChild, float xvel, float yvel) { // direction is always positive if we are sliding in the expanded direction float direction; if (mIsSlidingVertically){ - direction = mSlidingDirection == SlidingDirection.UP ? -yvel : yvel; + direction = mGravity == Gravity.BOTTOM ? -yvel : yvel; } else { - direction = mSlidingDirection == SlidingDirection.LEFT ? -xvel : xvel; + direction = mGravity == Gravity.RIGHT ? -xvel : xvel; } if (direction > 0 && mSlideOffset <= mAnchorPoint) { @@ -1658,7 +1644,7 @@ public int clampViewPositionVertical(View child, int top, int dy) { if(mIsSlidingVertically){ final int collapsedTop = computePanelTopPosition(0.f); final int expandedTop = computePanelTopPosition(1.0f); - if (mSlidingDirection == SlidingDirection.UP) { + if (mGravity == Gravity.BOTTOM) { return Math.min(Math.max(top, expandedTop), collapsedTop); } else { return Math.min(Math.max(top, collapsedTop), expandedTop); @@ -1675,7 +1661,7 @@ public int clampViewPositionHorizontal(View child, int left, int dx) { if(!mIsSlidingVertically) {// Horizontally final int collapsedLeft = computePanelLeftPosition(0.f); final int expandedLeft = computePanelLeftPosition(1.0f); - if (mSlidingDirection == SlidingDirection.LEFT) { + if (mGravity == Gravity.RIGHT) { return Math.min(Math.max(left, expandedLeft), collapsedLeft); } else { return Math.min(Math.max(left, collapsedLeft), expandedLeft);