diff --git a/README.md b/README.md index e1e4cf70..06aafa96 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,7 @@ or `?attr/actionBarSize` to support older API versions. * If you are using a custom `umanoDragView`, the panel will pass through the click events to the main layout. Make your second layout `clickable` to prevent this. * You can change the panel height by using the `setPanelHeight` method or `umanoPanelHeight` attribute. +* You can change the panel height relative to container height by using the `setPanelHeightOffset` method or `umanoPanelHeightOffset` attribute. * If you would like to hide the shadow above the sliding panel, set `shadowHeight` attribute to 0. * Use `setEnabled(false)` to completely disable the sliding panel (including touch and programmatic sliding) * Use `setTouchEnabled(false)` to disables panel's touch responsiveness (drag and click), you can still control the panel programatically diff --git a/library/res/values/attrs.xml b/library/res/values/attrs.xml index a3e8038d..c743e922 100644 --- a/library/res/values/attrs.xml +++ b/library/res/values/attrs.xml @@ -3,6 +3,7 @@ + diff --git a/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java b/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java index 5329d5b5..17b7d91b 100644 --- a/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java +++ b/library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java @@ -104,6 +104,11 @@ public class SlidingUpPanelLayout extends ViewGroup { */ private int mPanelHeight = -1; + /** + * The size offset of the overhang relative to height in pixels. + */ + private int mPanelHeightOffset = -1; + /** * The size of the shadow in pixels. */ @@ -320,6 +325,7 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) { if (ta != null) { mPanelHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoPanelHeight, -1); + mPanelHeightOffset = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoPanelHeightOffset, -1); mShadowHeight = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoShadowHeight, -1); mParallaxOffset = ta.getDimensionPixelSize(R.styleable.SlidingUpPanelLayout_umanoParallaxOffset, -1); @@ -440,6 +446,30 @@ public void setPanelHeight(int val) { } mPanelHeight = val; + mPanelHeightOffset = -1; + if (!mFirstLayout) { + requestLayout(); + } + + if (getPanelState() == PanelState.COLLAPSED) { + smoothToBottom(); + invalidate(); + return; + } + } + + /** + * Set the collapsed panel height offset in pixels + * + * @param val A height offset in pixels + */ + public void setPanelHeightOffset(int val) { + if (getPanelHeightOffset() == val) { + return; + } + + mPanelHeightOffset = val; + mPanelHeight = -1; if (!mFirstLayout) { requestLayout(); } @@ -481,6 +511,13 @@ public int getPanelHeight() { return mPanelHeight; } + /** + * @return The current collapsed panel height offset + */ + public int getPanelHeightOffset() { + return mPanelHeightOffset; + } + /** * @return The current parallax offset */ @@ -783,7 +820,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = layoutWidth; if (child == mMainView) { if (!mOverlayContent && mSlideState != PanelState.HIDDEN) { - height -= mPanelHeight; + height -= calculatePanelHeight(heightSize); } width -= lp.leftMargin + lp.rightMargin; @@ -818,7 +855,7 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { child.measure(childWidthSpec, childHeightSpec); if (child == mSlideableView) { - mSlideRange = mSlideableView.getMeasuredHeight() - mPanelHeight; + mSlideRange = mSlideableView.getMeasuredHeight() - calculatePanelHeight(heightSize); } } @@ -841,7 +878,8 @@ 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); + final int panelHeight = calculatePanelHeight(getMeasuredHeight()); + int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +panelHeight : -panelHeight); mSlideOffset = computeSlideOffset(newTop); break; default: @@ -1055,8 +1093,8 @@ private int computePanelTopPosition(float slideOffset) { int slidePixelOffset = (int) (slideOffset * mSlideRange); // Compute the top of the panel if its collapsed return mIsSlidingUp - ? getMeasuredHeight() - getPaddingBottom() - mPanelHeight - slidePixelOffset - : getPaddingTop() - slidingViewHeight + mPanelHeight + slidePixelOffset; + ? getMeasuredHeight() - getPaddingBottom() - calculatePanelHeight(getMeasuredHeight()) - slidePixelOffset + : getPaddingTop() - slidingViewHeight + calculatePanelHeight(getMeasuredHeight()) + slidePixelOffset; } /* @@ -1114,7 +1152,8 @@ public void setPanelState(PanelState state) { smoothSlideTo(1.0f, 0); break; case HIDDEN: - int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +mPanelHeight : -mPanelHeight); + final int panelHeight = calculatePanelHeight(getHeight()); + int newTop = computePanelTopPosition(0.0f) + (mIsSlidingUp ? +panelHeight : -panelHeight); smoothSlideTo(computeSlideOffset(newTop), 0); break; } @@ -1147,7 +1186,7 @@ private void onPanelDragged(int newTop) { // 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() - calculatePanelHeight(getHeight()); if (mSlideOffset <= 0 && !mOverlayContent) { // expand the main view @@ -1329,6 +1368,11 @@ public void onRestoreInstanceState(Parcelable state) { mSlideState = ss.mSlideState != null ? ss.mSlideState : DEFAULT_SLIDE_STATE; } + private int calculatePanelHeight(int heightSize) { + if (mPanelHeightOffset != -1) return heightSize - mPanelHeightOffset; + return mPanelHeight; + } + private class DragHelperCallback extends ViewDragHelper.Callback { @Override