Skip to content

Commit 2333f48

Browse files
committed
Merge pull request umano#96 from yous/master
Add layout_gravity option
2 parents f6380d8 + 0d3be0f commit 2333f48

File tree

1 file changed

+72
-11
lines changed

1 file changed

+72
-11
lines changed

library/src/com/sothree/slidinguppanel/SlidingUpPanelLayout.java

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import android.support.v4.widget.ViewDragHelper;
1515
import android.util.AttributeSet;
1616
import android.util.Log;
17+
import android.view.Gravity;
1718
import android.view.MotionEvent;
1819
import android.view.SoundEffectConstants;
1920
import android.view.View;
@@ -47,6 +48,13 @@ public class SlidingUpPanelLayout extends ViewGroup {
4748
*/
4849
private static final int DEFAULT_MIN_FLING_VELOCITY = 400; // dips per second
4950

51+
/**
52+
* Default attributes for layout
53+
*/
54+
private static final int[] DEFAULT_ATTRS = new int[] {
55+
android.R.attr.layout_gravity
56+
};
57+
5058
/**
5159
* Minimum velocity that will be detected as a fling
5260
*/
@@ -77,6 +85,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
7785
*/
7886
private int mShadowHeight = -1;
7987

88+
/**
89+
* True if the collapsed panel should be dragged up.
90+
*/
91+
private boolean mIsSlidingUp;
92+
8093
/**
8194
* True if a panel can slide with the current measurements
8295
*/
@@ -218,6 +231,18 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs) {
218231
public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
219232
super(context, attrs, defStyle);
220233
if (attrs != null) {
234+
TypedArray defAttrs = context.obtainStyledAttributes(attrs, DEFAULT_ATTRS);
235+
236+
if (defAttrs != null) {
237+
int gravity = defAttrs.getInt(0, Gravity.NO_GRAVITY);
238+
if (gravity != Gravity.TOP && gravity != Gravity.BOTTOM) {
239+
throw new IllegalArgumentException("layout_gravity must be set to either top or bottom");
240+
}
241+
mIsSlidingUp = gravity == Gravity.BOTTOM;
242+
}
243+
244+
defAttrs.recycle();
245+
221246
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.SlidingUpPanelLayout);
222247

223248
if (ta != null) {
@@ -530,7 +555,12 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
530555
mSlideRange = childHeight - mPanelHeight;
531556
}
532557

533-
final int childTop = lp.slideable ? slidingTop + (int) (mSlideRange * mSlideOffset) : paddingTop;
558+
final int childTop;
559+
if (mIsSlidingUp) {
560+
childTop = lp.slideable ? slidingTop + (int) (mSlideRange * mSlideOffset) : paddingTop;
561+
} else {
562+
childTop = lp.slideable ? slidingTop - (int) (mSlideRange * mSlideOffset) : paddingTop + mPanelHeight;
563+
}
534564
final int childBottom = childTop + childHeight;
535565
final int childLeft = paddingLeft;
536566
final int childRight = childLeft + child.getMeasuredWidth();
@@ -799,7 +829,9 @@ public void hidePane() {
799829

800830
private void onPanelDragged(int newTop) {
801831
final int topBound = getSlidingTop();
802-
mSlideOffset = (float) (newTop - topBound) / mSlideRange;
832+
mSlideOffset = mIsSlidingUp
833+
? (float) (newTop - topBound) / mSlideRange
834+
: (float) (topBound - newTop) / mSlideRange;
803835
dispatchOnPanelSlide(mSlideableView);
804836
}
805837

@@ -814,7 +846,11 @@ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
814846
if (mCanSlide && !lp.slideable && mSlideableView != null) {
815847
// Clip against the slider; no sense drawing what will immediately be covered.
816848
canvas.getClipBounds(mTmpRect);
817-
mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop());
849+
if (mIsSlidingUp) {
850+
mTmpRect.bottom = Math.min(mTmpRect.bottom, mSlideableView.getTop());
851+
} else {
852+
mTmpRect.top = Math.max(mTmpRect.top, mSlideableView.getBottom());
853+
}
818854
canvas.clipRect(mTmpRect);
819855
if (mSlideOffset < 1) {
820856
drawScrim = true;
@@ -848,7 +884,9 @@ boolean smoothSlideTo(float slideOffset, int velocity) {
848884
}
849885

850886
final int topBound = getSlidingTop();
851-
int y = (int) (topBound + slideOffset * mSlideRange);
887+
int y = mIsSlidingUp
888+
? (int) (topBound + slideOffset * mSlideRange)
889+
: (int) (topBound - slideOffset * mSlideRange);
852890

853891
if (mDragHelper.smoothSlideViewTo(mSlideableView, mSlideableView.getLeft(), y)) {
854892
setAllChildrenVisible();
@@ -880,8 +918,15 @@ public void draw(Canvas c) {
880918
}
881919

882920
final int right = mSlideableView.getRight();
883-
final int top = mSlideableView.getTop() - mShadowHeight;
884-
final int bottom = mSlideableView.getTop();
921+
final int top;
922+
final int bottom;
923+
if (mIsSlidingUp) {
924+
top = mSlideableView.getTop() - mShadowHeight;
925+
bottom = mSlideableView.getTop();
926+
} else {
927+
top = mSlideableView.getBottom();
928+
bottom = mSlideableView.getBottom() + mShadowHeight;
929+
}
885930
final int left = mSlideableView.getLeft();
886931

887932
if (mShadowDrawable != null) {
@@ -1010,11 +1055,20 @@ public void onViewPositionChanged(View changedView, int left, int top, int dx, i
10101055

10111056
@Override
10121057
public void onViewReleased(View releasedChild, float xvel, float yvel) {
1013-
int top = getSlidingTop();
1058+
int top = mIsSlidingUp
1059+
? getSlidingTop()
1060+
: getSlidingTop() - mSlideRange;
10141061

10151062
if (mAnchorPoint != 0) {
1016-
int anchoredTop = (int)(mAnchorPoint*mSlideRange);
1017-
float anchorOffset = (float)anchoredTop/(float)mSlideRange;
1063+
int anchoredTop;
1064+
float anchorOffset;
1065+
if (mIsSlidingUp) {
1066+
anchoredTop = (int)(mAnchorPoint*mSlideRange);
1067+
anchorOffset = (float)anchoredTop/(float)mSlideRange;
1068+
} else {
1069+
anchoredTop = mPanelHeight - (int)(mAnchorPoint*mSlideRange);
1070+
anchorOffset = (float)(mPanelHeight - anchoredTop)/(float)mSlideRange;
1071+
}
10181072

10191073
if (yvel > 0 || (yvel == 0 && mSlideOffset >= (1f+anchorOffset)/2)) {
10201074
top += mSlideRange;
@@ -1038,8 +1092,15 @@ public int getViewVerticalDragRange(View child) {
10381092

10391093
@Override
10401094
public int clampViewPositionVertical(View child, int top, int dy) {
1041-
final int topBound = getSlidingTop();
1042-
final int bottomBound = topBound + mSlideRange;
1095+
final int topBound;
1096+
final int bottomBound;
1097+
if (mIsSlidingUp) {
1098+
topBound = getSlidingTop();
1099+
bottomBound = topBound + mSlideRange;
1100+
} else {
1101+
bottomBound = getPaddingTop();
1102+
topBound = bottomBound - mSlideRange;
1103+
}
10431104

10441105
return Math.min(Math.max(top, topBound), bottomBound);
10451106
}

0 commit comments

Comments
 (0)