Search code examples
androidnavigation-drawerandroid-support-libraryandroid-navigationview

NavigationDrawer height collapses to that of the Toolbar after onPause on some devices


I have a fairly simple application that has a custom Toolbar with a NavigationDrawer. Apart from these items I have a GLSurfaceView that fills the entire screen. In my NavigationDrawer I have a list of cases that can be selected and then data is fetched and rendered in the GLSurfaceView.

Everything is working fine, except one thing: When the application is paused and then resumed, the height of the NavigationView collapses to that of the Toolbar. The NavigationView can still be scrolled in that small height and when a case is selected at that point, the NavigationView's height is refreshed and everything goes back to normal. This therefore also happens on rotation of the device.

Note that if the NavigationView is visible when rotating/pausing the app, the issue does not occur.

This issue does not happen on all devices though. Here is a list I have tested on:

Issue appears on:

  • Samsung Galaxy S2 Tab: Android 6.0.1
  • Samsung Galaxy S7 Edge: Android 6.0.1
  • HTC One A9s: Android 6.0
  • Samsung Galaxy Note 10.1: Android 5.11

The issue does not appear on:

  • Sony Xperia XZ: Android 6.0.1
  • Huawei Honor 7: Android 5.0.2
  • Huawei Nexus P6: Android 7.0

I have tried invalidating all the views in onPause, but nothing helps and I cannot figure out where I am doing something wrong.

Other notes:

  • compileSdkVersion = 25
  • targetSdkVersion = 25
  • Support library version: 25.2.0
  • Build tools version: 25.0.2
  • Gradle plugin version: 2.3.0 / Android Studio 2.3

styles.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <!-- This style is set in AndroidManifest.xml -->
    <style name="DemoTheme" parent="Theme.AppCompat.Light.DarkActionBar">

        <!-- To be able to use a custom Toolbar. -->
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>

        <item name="colorPrimary">@color/demo_color_main_brand</item>
        <item name="colorPrimaryDark">@color/demo_color_extras_darkblue</item>
        <item name="colorAccent">@color/demo_color_extras_lightgreen</item>

    </style>

    <style name="DemoActionBarStyle" parent="@style/Widget.AppCompat.ActionBar">
        <item name="android:theme">@style/ThemeOverlay.AppCompat.Dark.ActionBar</item>
        <item name="popupTheme">@style/ThemeOverlay.AppCompat.Light</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:background">@color/demo_color_main_brand</item>
        <item name="android:minHeight">?attr/actionBarSize</item>
    </style>

   ...

</resources>

activity_demo.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/demo_drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Wrap Toolbar in AppBarLayout to add shadow below the Toolbar. -->
        <android.support.design.widget.AppBarLayout
            android:id="@+id/demo_appbarlayout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <android.support.v7.widget.Toolbar
                android:id="@+id/demo_toolbar"
                style="@style/DemoActionBarStyle" />

        </android.support.design.widget.AppBarLayout>

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/demo_appbarlayout" >

            <android.support.design.widget.CoordinatorLayout
                android:id="@+id/fv_coordinatorlayout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".activities.DemoActivity" >

                <com.my.company.demo.views.DemoGLSurfaceView
                    android:id="@+id/demo_glsurfaceview"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:visibility="visible" />

            </android.support.design.widget.CoordinatorLayout>

        </FrameLayout>

    </RelativeLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/demo_navigationview"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:headerLayout="@layout/demo_navigationview_header"
        app:menu="@menu/demo_navigationview_menu"
        app:itemIconTint="@drawable/demo_colors_navigationview"
        app:itemTextColor="@drawable/demo_colors_navigationview" />

</android.support.v4.widget.DrawerLayout>

onCreate in DemoActivity:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_demo);

    // Setup Toolbar.
    Toolbar toolbar = (Toolbar) findViewById(R.id.demo_toolbar);
    setSupportActionBar(toolbar);

    // Setup NavigationView.
    NavigationView navigationView = (NavigationView) findViewById(R.id.demo_navigationview);
    navigationView.setNavigationItemSelectedListener(this);

    // Setup DrawerLayout.
    DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.demo_drawer_layout);
    ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(
            this, drawerLayout, toolbar, R.string.app_name, R.string.app_name);
    drawerLayout.addDrawerListener(actionBarDrawerToggle);
    actionBarDrawerToggle.syncState();

    // Load demo cases.
    mModuleConfiguration = new ModuleConfiguration(getString(R.string.module_config_url), this);
}

Before rotation:

enter image description here

After rotation:

enter image description here


Solution

  • I found a similar issue that helped med fix my problem here. The gist of it is to implement an extra DrawerLayout.DrawerListener in the Activity and do

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset)
    {
        mDrawerLayout.bringChildToFront(drawerView);
        mDrawerLayout.requestLayout();
    }
    

    to ensure that the drawer is drawn above the GLSurfaceView.

    Steps to fix:

    1. Implement DrawerLayout.DrawerListener in the Activity.
    2. Add both an ActionBarDrawerToggle and the Activity as listeners for the DrawerLayout.
    3. Implement the above onDrawerSlide() method from the DrawerLayout.DrawerListener interface (mDrawerLayout is simply a local reference to the DrawerLayout).