I have implemented UmanoSlidingPanel using https://github.com/umano/AndroidSlidingUpPanel . Everything is working fine except that my sliding panel when expanded, the sliding content (sliding_view) is going below the status bar. How can I avoid that?I tried removing
<item name="android:windowTranslucentStatus">true</item>
from styles.xml but that makes the status bar non-tranlucent for the main content also. Any way to fix this?
<com.sothree.slidinguppanel.SlidingUpPanelLayout xmlns:sothree="http://schemas.android.com/apk/res-auto"
android:id="@+id/sliding_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
sothree:umanoDragView="@+id/firstPanelDragArea"
sothree:umanoPanelHeight="@dimen/bottom_panel_height"
sothree:umanoShadowHeight="4dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/toolbar"
layout="@layout/toolbar" />
<FrameLayout
android:id="@+id/frame_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<!-- SLIDING LAYOUT -->
<LinearLayout
android:id="@+id/firstPanelDragArea"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/sliding_view" />
</LinearLayout>
styles.xml
<style name="AppTheme" parent="@style/Theme.AppCompat">
<item name="windowActionBar">false</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:windowTranslucentStatus">true</item>
<item name="windowNoTitle">true</item>
</style>
EDIT
public void onPanelSlide(View panel, float slideOffset) {
if (slideOffset > 0.5 && !flagTransparent) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
flagTransparent = true;
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
} else if (slideOffset < 0.5 && flagTransparent){
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
flagTransparent = false;
Log.i(TAG, "onPanelSlide, offset " + slideOffset);
}
1) Have a look at the following Gist I created.
The file sliding_up_activity.xml
could be the activity layout that will include your sliding up panel view.
It is in there where you should set android:fitsSystemWindows="true"
so that any children is inset properly not o fall behind the action bar or nav bar.
The file sliding_view.xml
could be your sliding up view.
You should not need to do anything else in any of the panel callbacks.
You can safely remove the translucent style and the code inside the onPanelSlide()
. This should result with a sliding panel properly inset such that never goes behind the status or nav bars.
Alternatively, if you don't have the same architecture, you could forget about the sliding_up_activity.xml
and set android:fitsSystemWindows="true"
in the CoordinatorLayout
instead, in sliding_view.xml
.
2) The second thing we were talking, is making the status bar translucent, letting the sliding up panel fall behind the status bar and then smoothly add padding to properly inset the contents.
For that, set android:fitsSystemWindows="false"
or remove it from any possible parent your sliding up panel has.
Then in onPanelSlide
you could do something like this
if (slideOffset >= ANCHOR_POINT) {
// adjust the span of the offset
float offset = (slideOffset - ANCHOR_POINT) / (1 - ANCHOR_POINT);
// the padding top will be the base original padding plus a percentage of the status
// bar height
float paddingTop = mSlidePanelBasePadding + offset * mStatusBarInset;
// apply the padding to the header container
mContainer.setPadding(0, (int) paddingTop, 0, 0);
}
where:
mSlidePanelBasePadding
would be the initial padding of you sliding up panelmStatusBarInset
would be the status bar height.
That should add padding to your slidingUp panel progressively when it gets past the anchor point.
You can get the status bar height like this:
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
I hope this helps a bit.
Found another solution to the problem by making changes in onMeasure method of SlidingUpPanelLayout.java . Posting the code for future readers.Need to add 4 lines of code.
SlidingPanelLayout.java
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Width must have an exact value or MATCH_PARENT");
} else if (heightMode != MeasureSpec.EXACTLY) {
throw new IllegalStateException("Height must have an exact value or MATCH_PARENT");
}
final int childCount = getChildCount();
if (childCount != 2) {
throw new IllegalStateException("Sliding up panel layout must have exactly 2 children!");
}
mMainView = getChildAt(0);
mSlideableView = getChildAt(1);
if (mDragView == null) {
setDragView(mSlideableView);
}
// If the sliding panel is not visible, then put the whole view in the hidden state
if (mSlideableView.getVisibility() != VISIBLE) {
mSlideState = PanelState.HIDDEN;
}
int layoutHeight = heightSize - getPaddingTop() - getPaddingBottom();
int layoutWidth = widthSize - getPaddingLeft() - getPaddingRight();
// First pass. Measure based on child LayoutParams width/height.
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
final LayoutParams lp = (LayoutParams) child.getLayoutParams();
// We always measure the sliding panel in order to know it's height (needed for show panel)
if (child.getVisibility() == GONE && i == 0) {
continue;
}
int height = layoutHeight;
int width = layoutWidth;
if (child == mMainView) {
if (!mOverlayContent && mSlideState != PanelState.HIDDEN) {
height -= mPanelHeight;
}
width -= lp.leftMargin + lp.rightMargin;
} 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;.
// START OF CODE CHANGES
if (height < SCREEN_HEIGHT) { //SCREEN_HEIGHT = 900
height = height - MARGIN_BOTTOM; //MARGIN_BOTTOM = 8
} else {
height = height - getStatusBarHeight();
}
// END OF CODE CHANGES
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
Try android:fitsSystemWindows="true"
in the parent layout. That should fix your problem.
Another solution I have implemented in the past is, in the activity that contains the slidingUpPanel, you can style it with a translucent status bar (API >= 19):
<item name="android:windowTranslucentStatus">true</item>
And then in onPanelSlide
callback, you can modify the padding of your slidingUpPanel adding progressively until the panel is fully up. In that moment the amount of added extra padding should be the status bar dimensions.
来源:https://stackoverflow.com/questions/34725871/sliding-layout-below-status-bar-in-umano-slidingpanel