SlidingMenu icon indicating copy to clipboard operation
SlidingMenu copied to clipboard

Lollipop Bottom Nav Bar Overlays App When Moving Action Bar

Open jjanusch opened this issue 10 years ago • 43 comments

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 4 Running Kit Kat

Nexus 5 running Lollipop: 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.

jjanusch avatar Nov 03 '14 22:11 jjanusch

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.

karanbhatia avatar Nov 04 '14 06:11 karanbhatia

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.

ahornerr avatar Nov 04 '14 18:11 ahornerr

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);
        }
    }

ahornerr avatar Nov 18 '14 19:11 ahornerr

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.

andj207 avatar Dec 05 '14 10:12 andj207

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). screenshot

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).

Den-Rimus avatar Dec 11 '14 11:12 Den-Rimus

I added mine as a library module too. Den-Rimus's solution worked for me as well. Many thanks! :+1:

pheebner avatar Dec 29 '14 20:12 pheebner

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
);

pheebner avatar Dec 30 '14 01:12 pheebner

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...

patelakshay13890 avatar Jan 07 '15 08:01 patelakshay13890

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
     */

pheebner avatar Jan 07 '15 22:01 pheebner

Can u provide me lib. jar or Source code that u have made changes ? Waiting for positive response ..!!!!

patelakshay13890 avatar Jan 16 '15 06:01 patelakshay13890

Adding padding is a ugly workaround. This solution works best as in doesn't need to change the lib source code.

GoMino avatar Jan 20 '15 15:01 GoMino

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 .

patelakshay13890 avatar Jan 22 '15 11:01 patelakshay13890

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...!!!

patelakshay13890 avatar Jan 22 '15 11:01 patelakshay13890

are you calling setSupportActionBar(yourtoolbar) from your activity after setContentView ?

GoMino avatar Jan 23 '15 13:01 GoMino

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 .

patelakshay13890 avatar Jan 24 '15 05:01 patelakshay13890

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 .

patelakshay13890 avatar Jan 24 '15 05:01 patelakshay13890

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);

travisw88 avatar Feb 11 '15 16:02 travisw88

@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" />     

travisw88 avatar Feb 11 '15 16:02 travisw88

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!

moritzm avatar Feb 24 '15 14:02 moritzm

I posted this on Stack Overflow too https://stackoverflow.com/questions/28693442/android-lollipop-navigation-bar-overlays-activity-view/28698322#28698322

moritzm avatar Feb 24 '15 14:02 moritzm

@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.

hidroh avatar May 21 '15 09:05 hidroh

It is still not working on OnePlus One A0001. #723 what should i do???!

jjhesk avatar Jul 06 '15 06:07 jjhesk

I was having a blank space on the top and Den-Rimus solution applied in different way to the topPadding worked for me.

gramland avatar Jul 09 '15 17:07 gramland

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.

TrevorPage avatar Jul 11 '15 20:07 TrevorPage

@Den-Rimus :: You helped me out brov. resolved my issues.

jigar92 avatar Jul 24 '15 05:07 jigar92

@Den-Rimus You are great, my friend... you are the hero :)

smoothumut avatar Jul 29 '15 12:07 smoothumut

great

xing634325131 avatar Jul 31 '15 10:07 xing634325131

great, thank you. I use gradle so i've extended SlidingMenu to a custom class and add your fix, works like a charm.

marshallino16 avatar Aug 12 '15 11:08 marshallino16

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).

Den-Rimus avatar Sep 03 '15 15:09 Den-Rimus

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>

sumknot avatar Nov 26 '15 03:11 sumknot