SlidingMenu
SlidingMenu copied to clipboard
Lollipop Bottom Nav Bar Overlays App When Moving Action Bar
When compiling for API 21 using build tools 21.1 and deploying to the latest Lollipop dev build (LPX13D), app content goes behind the bottom navigation bar. I cannot duplicate in Kit Kat. I've tried both using the SlidingFragmentActivity and doing everything manually myself. If I set it to to SlidingMenu.SLIDING_CONTENT rather than SlidingMenu.SLIDING_WINDOW, the issue goes away.
You can see what I refer to here:
Nexus 4 running Kit Kat:

Nexus 5 running Lollipop:

That is the same page in Kit Kat and Lollipop. The page is only a ScrollView with text in it and no Java whatsoever save for initializing the menu. Both devices are scrolled to the bottom and the Lollipop version is hidden behind the navigation bar at the bottom.
If I don't enable the SlidingMenu (by not calling attachToActivity()), this issue does not arise.
I have the same exact issue, and have narrowed it down to a certain configuration.
I can reproduce the issue on a Nexus 5 running the Lollipop preview using the latest AppCompat library with the material action bar. If I use a Holo theme on the Nexus 5 w/ Lollipop preview, the issue goes away.
On a phone running 4.4.4 an below, using Material action bar or not doesnt matter-- it always works.
Thanks!
Edit. Also wanted to confirm with the above post, that setting the sliding menu to SLIDING_CONTENT causes the issue to go away.
I also have this issue using the SlidingFragmentActivity which extends ActionBarActivity. I'm so glad I found this, I was starting to think I was going crazy. Nexus 5 running the latest Lollipop preview, AppCompat theme with the material Toolbar and ActionBar.
I think it's related to the ActionBar pushing down the content and the SlidingMenu not recognizing the new ActionBar.
BaseActivity.java
public void onCreate() {
setBehindContentView(R.layout.menu_frame);
setContentView(R.layout.content_frame);
}
content_frame.xml
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include layout="@layout/toolbar" />
<LinearLayout
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" />
</LinearLayout>
</FrameLayout>
toolbar.xml
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
app:theme="@style/MyTheme.ActionBar" />
Where @id/main_content contains the fragments that get replaced.
I implemented a temporary fix. It's not perfect but it does the job. It sets bottom padding on both the content frame and behind menu.
private int getNavigationBarHeight() {
Resources resources = getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
@Override
public void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
int navBarHeight = getNavigationBarHeight();
findViewById(R.id.base_frame).setPadding(0, 0, 0, navBarHeight);
findViewById(R.id.menu_frame).setPadding(0, 0, 0, navBarHeight);
}
}
Hi I have found a better solution to fix this. It's about the layout params when the CustomViewAbove and CustomViewBehind initiated in the SlideMenu creation.
Change from:
LayoutParams behindParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mViewBehind = new CustomViewBehind(context);
addView(mViewBehind, behindParams);
LayoutParams aboveParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
mViewAbove = new CustomViewAbove(context);
addView(mViewAbove, aboveParams);
to this fix:
int width = getResources().getDisplayMetrics().widthPixels,
height = getResources().getDisplayMetrics().heightPixels,
statusBarHeight = getStatusBarHeight();
height = height - statusBarHeight;
LayoutParams behindParams = new LayoutParams(width, height);
mViewBehind = new CustomViewBehind(context);
addView(mViewBehind, behindParams);
LayoutParams aboveParams = new LayoutParams(width, height);
mViewAbove = new CustomViewAbove(context);
addView(mViewAbove, aboveParams);
This works for me. Try if it can help you though.
In my project SlidingMenu library is added as library-module. So I have access to library sources.
My problem was that my app's content went behind android's bottom navigation bar (on screen highlighted in purple).

The best idea is to fix this in SlidingMenu's code.
In file YOUR-PROJECT-UNDER-GRADLE/sliding-menu/src/com/jeremyfeinstein/slidingmenu/lib/SlidingMenu.java,
protected boolean fitSystemWindows(Rect insets) method replace
int bottomPadding = insets.bottom;
with next:
int bottomPadding = insets.bottom;
if (Build.VERSION.SDK_INT >= 21) {
Resources resources = getContent().getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
bottomPadding += resources.getDimensionPixelSize(resourceId);
}
}
Now works like a charm (at least for me).
I added mine as a library module too. Den-Rimus's solution worked for me as well. Many thanks! :+1:
I did a little more research and discovered that in order for this solution to work in landscape, I had to use the identifier "navigation_bar_width" like so:
private int getNavBarWidth() {
Resources r = getResources();
int id = r.getIdentifier("navigation_bar_width", "dimen", "android");
return r.getDimensionPixelSize(id);
}
And in order to set the padding correctly depending on the position of the navigation bar:
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
switch (manager.getDefaultDisplay().getRotation()) {
case Surface.ROTATION_90:
rect.right += getNavBarWidth();
break;
case Surface.ROTATION_180:
rect.top += getNavBarHeight();
break;
case Surface.ROTATION_270:
rect.left += getNavBarWidth();
break;
default:
rect.bottom += getNavBarHeight();
}
setPadding(
rect.left, rect.top, rect.right, rect.bottom
);
Does any one know how to use this Sliding Menu with latest app compact V21 ?? I badly require this in my project.. plz do reply fast & expecting +eve response...
Hello Akshay,
I'm not sure what problems you might be having, but I'm using it with appcompat 21.0.3. I'm using it as a library module and made these changes. It works fine for me!
build.gradle file of library:
apply plugin: 'com.android.library'
repositories {
mavenCentral()
}
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
minSdkVersion 11
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
changes to SlidingMenu.java:
/*
fixed bug when used in lollipop
*/
/* (non-Javadoc)
* @see android.view.ViewGroup#fitSystemWindows(android.graphics.Rect)
*/
@SuppressLint("NewApi")
@Override
protected boolean fitSystemWindows(Rect insets) {
if (mActionbarOverlay) return true;
setMyPadding(insets);
return true;
}
@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (mActionbarOverlay) return insets.consumeSystemWindowInsets();
Rect rect = new Rect(
insets.getSystemWindowInsetLeft(),
insets.getSystemWindowInsetTop(),
insets.getSystemWindowInsetRight(),
insets.getSystemWindowInsetBottom()
);
setMyPadding(rect);
return insets.consumeSystemWindowInsets();
}
private void setMyPadding(Rect rect) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
WindowManager manager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
switch (manager.getDefaultDisplay().getRotation()) {
case Surface.ROTATION_90:
rect.right += getNavBarWidth();
break;
case Surface.ROTATION_180:
rect.top += getNavBarHeight();
break;
case Surface.ROTATION_270:
rect.left += getNavBarWidth();
break;
default:
rect.bottom += getNavBarHeight();
}
}
setPadding(
rect.left, rect.top, rect.right, rect.bottom
);
}
private int getNavBarWidth() {
return getNavBarDimen("navigation_bar_width");
}
private int getNavBarHeight() {
return getNavBarDimen("navigation_bar_height");
}
private int getNavBarDimen(String resourceString) {
Resources r = getResources();
int id = r.getIdentifier(resourceString, "dimen", "android");
if (id > 0) {
return r.getDimensionPixelSize(id);
} else {
return 0;
}
}
/*
END BUG FIX
*/
Can u provide me lib. jar or Source code that u have made changes ? Waiting for positive response ..!!!!
Adding padding is a ugly workaround. This solution works best as in doesn't need to change the lib source code.
However when I use this Lib. with Theme.AppCompat.Light.DarkActionBar theme Sliding Menu Work Perfectly in 4.1.2 & above. But With Using Theme.AppCompat theme & ToolBar i.e. no ActionBar then there is a problem i got It Slides ToolBar also... What Could be the Reason ? Expecting +ve & quick response...!!!
On Tue, Jan 20, 2015 at 9:20 PM, Amine Bezzarga [email protected] wrote:
Adding padding is a ugly workaround. This http://stackoverflow.com/a/27535016/795245 solution works best as in doesn't need to change the lib source code.
— Reply to this email directly or view it on GitHub https://github.com/jfeinstein10/SlidingMenu/issues/680#issuecomment-70675372 .
However when I use this Lib. with Theme.AppCompat.Light.DarkActionBar theme Sliding Menu Work Perfectly in 4.1.2 & above. But With Using Theme.AppCompat theme & ToolBar i.e. no ActionBar then there is a problem i got It Slides ToolBar also... What Could be the Reason ? Expecting +ve & quick response...!!!
are you calling setSupportActionBar(yourtoolbar) from your activity after setContentView ?
no..
On Fri, Jan 23, 2015 at 6:42 PM, Amine Bezzarga [email protected] wrote:
are you calling setSupportActionBar(yourtoolbar) from your activity after setContentView ?
— Reply to this email directly or view it on GitHub https://github.com/jfeinstein10/SlidingMenu/issues/680#issuecomment-71191028 .
why ? how to achieve this ?
On Sat, Jan 24, 2015 at 11:02 AM, akshay patel [email protected] wrote:
no..
On Fri, Jan 23, 2015 at 6:42 PM, Amine Bezzarga [email protected] wrote:
are you calling setSupportActionBar(yourtoolbar) from your activity after setContentView ?
— Reply to this email directly or view it on GitHub https://github.com/jfeinstein10/SlidingMenu/issues/680#issuecomment-71191028 .
Adding the following lines to the SlidingMenu constructors has worked for me. I didn't have to make any other code changes.
if(Build.VERSION.SDK_INT >= 21)
setSystemUiVisibility(SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
@patelakshay13890 In order to prevent your toolbar from sliding along with your content, you can put the following in slidingmenumain.xml inside the SlidingMenu element.
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:layout_alignParentTop="true"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" />
Look at this solution https://stackoverflow.com/questions/27165690/the-getdecorview-method-return-view-include-navigation-bar-view-on-lollipop/27535016#27535016
<style name="Theme" parent="FrameworkRoot.Theme">
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
</style>
This worked perfectly for me!
I posted this on Stack Overflow too https://stackoverflow.com/questions/28693442/android-lollipop-navigation-bar-overlays-activity-view/28698322#28698322
@pheebner solution works, but it creates a gap at bottom for devices with physical navigation bar (e.g. Samsung Note 4). @moritzm solution works, but as pointed out in StackOverflow thread it takes away colour of status bar as well. @travisw88 solution works and poses no problems for me so far. I see no problems with both physical and on screen navigation bar for Lollipop devices.
It is still not working on OnePlus One A0001. #723 what should i do???!
I was having a blank space on the top and Den-Rimus solution applied in different way to the topPadding worked for me.
Thanks to all above for posting these solutions. It's a shame and a worry that the library doesn't seem to be receiving updates. I wonder if anyone has a more active fork of this or an alternative library.
@Den-Rimus :: You helped me out brov. resolved my issues.
@Den-Rimus You are great, my friend... you are the hero :)
great
great, thank you. I use gradle so i've extended SlidingMenu to a custom class and add your fix, works like a charm.
I myself vote for @travisw88 's fix. Mine stroke me in the back giving empty space in the bottom of screen on devices with hardware navigation buttons (and those are lot's of samsungs, HTCs, LGs and so on).
mark. i got the same issue and finally resolved with @travisw88 's code.
btw, @Den-Rimus 's code is fine but i got a blank bottom padding area on device has no navigation bar.
and also the following code has side effects, the custom status bar color will be lost
<item name="android:windowDrawsSystemBarBackgrounds">false</item>