Skip to content

Commit 11ce289

Browse files
Alberto Manzano TorregrosaAlberto Manzano Torregrosa
Alberto Manzano Torregrosa
authored and
Alberto Manzano Torregrosa
committed
Added panelOffScreen option to keep sliding until the panel is located off screen (above or below, depending on the gravity)
1 parent eac02ad commit 11ce289

File tree

4 files changed

+71
-3
lines changed

4 files changed

+71
-3
lines changed

demo/res/layout/activity_demo.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@
1515
sothree:umanoParallaxOffset="100dp"
1616
sothree:umanoDragView="@+id/dragView"
1717
sothree:umanoOverlay="true"
18-
sothree:umanoScrollableView="@+id/list">
18+
sothree:umanoScrollableView="@+id/list"
19+
sothree:panelOffScreen="true">
1920

2021
<!-- MAIN CONTENT -->
2122
<FrameLayout

library/res/values/attrs.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<attr name="umanoOverlay" format="boolean"/>
1313
<attr name="umanoClipPanel" format="boolean"/>
1414
<attr name="umanoAnchorPoint" format="float" />
15+
<attr name="panelOffScreen" format="boolean" />
1516
<attr name="umanoInitialState" format="enum">
1617
<enum name="expanded" value="0" />
1718
<enum name="collapsed" value="1" />

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

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.sothree.slidinguppanel;
22

33
import android.annotation.SuppressLint;
4+
import android.annotation.TargetApi;
45
import android.content.Context;
56
import android.content.res.TypedArray;
67
import android.graphics.Canvas;
78
import android.graphics.Paint;
89
import android.graphics.PixelFormat;
10+
import android.graphics.Point;
911
import android.graphics.Rect;
1012
import android.graphics.drawable.Drawable;
1113
import android.os.Build;
@@ -16,10 +18,12 @@
1618
import android.support.v4.view.ViewCompat;
1719
import android.support.v7.widget.RecyclerView;
1820
import android.util.AttributeSet;
21+
import android.util.Log;
1922
import android.view.Gravity;
2023
import android.view.MotionEvent;
2124
import android.view.View;
2225
import android.view.ViewGroup;
26+
import android.view.WindowManager;
2327
import android.view.accessibility.AccessibilityEvent;
2428
import android.widget.ListView;
2529
import android.widget.ScrollView;
@@ -41,6 +45,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
4145
*/
4246
private static final float DEFAULT_ANCHOR_POINT = 1.0f; // In relative %
4347

48+
/**
49+
* Default position of the panel
50+
*/
51+
private static final boolean DEFAULT_PANEL_OFF_SCREEN = false;
52+
4453
/**
4554
* Default initial state for the component
4655
*/
@@ -105,6 +114,11 @@ public class SlidingUpPanelLayout extends ViewGroup {
105114
*/
106115
private int mPanelHeight = -1;
107116

117+
/**
118+
* True if we want to slide the visible panel off screen; false by default
119+
*/
120+
private boolean mPanelOffScreen;
121+
108122
/**
109123
* The size of the shadow in pixels.
110124
*/
@@ -212,6 +226,8 @@ public enum PanelState {
212226

213227
private final ViewDragHelper mDragHelper;
214228

229+
private Context mContext;
230+
215231
/**
216232
* Stores whether or not the pane was expanded the last time it was slideable.
217233
* If expand/collapse operations are invoked this state is modified. Used by
@@ -299,6 +315,8 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs) {
299315
public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
300316
super(context, attrs, defStyle);
301317

318+
mContext = context;
319+
302320
if (isInEditMode()) {
303321
mShadowDrawable = null;
304322
mDragHelper = null;
@@ -334,6 +352,8 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
334352
mAnchorPoint = ta.getFloat(R.styleable.SlidingUpPanelLayout_umanoAnchorPoint, DEFAULT_ANCHOR_POINT);
335353

336354
mSlideState = PanelState.values()[ta.getInt(R.styleable.SlidingUpPanelLayout_umanoInitialState, DEFAULT_SLIDE_STATE.ordinal())];
355+
356+
mPanelOffScreen = ta.getBoolean(R.styleable.SlidingUpPanelLayout_panelOffScreen, DEFAULT_PANEL_OFF_SCREEN);
337357
}
338358

339359
ta.recycle();
@@ -374,6 +394,13 @@ public SlidingUpPanelLayout(Context context, AttributeSet attrs, int defStyle) {
374394
@Override
375395
protected void onFinishInflate() {
376396
super.onFinishInflate();
397+
398+
if (mPanelOffScreen) {
399+
// Get scrollable view (always second child) and expand its size in order to put
400+
// the panel above the screen
401+
View slidingUpPanelLayout = getChildAt(1);
402+
setExpandedPanelOffScreen(slidingUpPanelLayout);
403+
}
377404
if (mDragViewResId != -1) {
378405
setDragView(findViewById(mDragViewResId));
379406
}
@@ -382,6 +409,30 @@ protected void onFinishInflate() {
382409
}
383410
}
384411

412+
/**
413+
* Expands the height of the SlidingUpPanelLayout by 'mPanelHeight' so that there's no
414+
* empty space at the bottom when the view is expanded
415+
*
416+
* @param slidingUpPanelLayout (SlidingUpPanelLayout)
417+
*/
418+
@TargetApi(13)
419+
public void setExpandedPanelOffScreen(View slidingUpPanelLayout) {
420+
if (slidingUpPanelLayout != null) {
421+
// Get screen dimensions
422+
final Point size = new Point();
423+
((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getSize(size);
424+
final int screenHeight = size.y;
425+
final int screenWidth = size.x;
426+
427+
SlidingUpPanelLayout.LayoutParams params;
428+
params = new SlidingUpPanelLayout.LayoutParams(screenWidth, screenHeight + mPanelHeight);
429+
430+
slidingUpPanelLayout.setLayoutParams(params);
431+
} else {
432+
Log.e(TAG, "slidingUpPanelLayout is null in setExpandedPanelOffScreen");
433+
}
434+
}
435+
385436
public void setGravity(int gravity) {
386437
if (gravity != Gravity.TOP && gravity != Gravity.BOTTOM) {
387438
throw new IllegalArgumentException("gravity must be set to either top or bottom");
@@ -799,14 +850,29 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
799850

800851
child.measure(childWidthSpec, childHeightSpec);
801852

802-
if (child == mSlideableView) {
853+
if (mPanelOffScreen) {
854+
// In order to place the panel off the screen,
855+
// the sliding distance will be the height of the entire sliding view
856+
// minus the panel height and the notification bar
857+
mSlideRange = mSlideableView.getMeasuredHeight() - mPanelHeight - getNotificationBarHeight();
858+
} else {
803859
mSlideRange = mSlideableView.getMeasuredHeight() - mPanelHeight;
804860
}
805861
}
806862

807863
setMeasuredDimension(widthSize, heightSize);
808864
}
809865

866+
// Returns the height of the notification bar
867+
private int getNotificationBarHeight() {
868+
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
869+
if (resourceId > 0) {
870+
return getResources().getDimensionPixelSize(resourceId);
871+
} else {
872+
return 0;
873+
}
874+
}
875+
810876
@Override
811877
protected void onLayout(boolean changed, int l, int t, int r, int b) {
812878
final int paddingLeft = getPaddingLeft();

maven_push.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ afterEvaluate { project ->
1919
pom.artifactId = POM_ARTIFACT_ID
2020

2121
repository(url: sonatypeRepositoryUrl) {
22-
authentication(userName: nexusUsername, password: nexusPassword)
22+
authentication(userName: "", password: "")
2323
}
2424

2525
pom.project {

0 commit comments

Comments
 (0)