DrawerLayout on top of Actionbar

13,582

Solution 1

I searched the web in order to find any good solution for this problem and haven't found. So I did a trick that did this.

First of all we need to request action bar overlay feature. So in onCreate() of your activity, before setContntView() call: requestWindowFeature(com.actionbarsherlock.view.Window.FEATURE_ACTION_BAR_OVERLAY);

It will make everything including navigation drawer draw behind action bar. We don't need this, so we need to set the top margin of our FrameLayout which hosts our fragments in the activity with the exact height of the action bar. In the layout file of the activity we need to do the following:

<!-- Framelayout to display Fragments -->

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize" />

It will make only navigation drawer appear behind the action bar. Now we will hide the action bar when the navigation drawer is opened on half, and will show it when the drawer is nearly closed. To do this we need to make the following in the activity:

@Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
        super.onDrawerSlide(drawerView, slideOffset);

        if(slideOffset > 0.5){
            actionBar.setBackgroundDrawable(null);
            actionBar.hide();
        } else {
            actionBar.show();

            if(slideOffset < 0.1){
                actionBar.setBackgroundDrawable(layerDrawable);
            }
        }       
    }

As you can see I also change the background drawable of the action bar to make it transparent when before I begin to hide it, and change it back with my custom background when I show it back.

My custom background is a layerListDrawable which is all transparent but have a divider in bottom with some shadow.

And to achieve this I have defined the following layer-list in XML:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
        <shape android:shape="rectangle">
            <solid android:color="@android:color/transparent"/>
        </shape>
    </item>

    <item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
        <shape android:shape="rectangle">
            <solid android:color="#afafaf"/>
        </shape>
    </item>

    <item android:top="0dp" android:left="0dp" android:bottom="0dp" android:right="0dp">
        <shape android:shape="rectangle">
            <gradient
                android:angle="270"
                android:startColor="#88afafaf" 
                android:endColor="#33afafaf"
            />
        </shape>
    </item>    
</layer-list>

And to get the background I need from this XML I do the following in the activity:

final ActionBar actionBar = getSupportActionBar();
        final LayerDrawable layerDrawable = (LayerDrawable) getResources()
                .getDrawable(R.drawable.shadow_divider);

        final TypedArray styledAttributes = getTheme().obtainStyledAttributes(
                new int[] { R.attr.actionBarSize });
        int topOffset = (int) (styledAttributes.getDimension(0, 0));
        styledAttributes.recycle();

        layerDrawable.setLayerInset(1, 0, topOffset - 3, 0, 2);
        layerDrawable.setLayerInset(2, 0, topOffset - 2, 0, 0);

        actionBar.setBackgroundDrawable(layerDrawable);

where R.drawable.shadow_divider is the XML layer-list I have defined earlier.

It looks really great! Hope it can help someone.

EDIT

I had a small bug here which can be a reason of a crush sometimes. Here is the fixed code: `

    <FrameLayout
        android:id="@+id/frame_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        **android:paddingTop="?attr/actionBarSize"**  />`

It should be paddingTop not layout_marginTop!

Solution 2

I don't think you'll be able to do this with Android's provided Navigation Drawer (without doing something really hacky), since doing this really goes against Android design patterns. If you want a library that does what you're looking for, I've used this library before Android came out with it's own widget, and it does what you're looking for.

Solution 3

I found the answer in my question, also added an example project for reference. You can take a look to see if it works for you. Android Navigation Drawer on top ActionBar

Solution 4

That's the proper effect in Android defaults. If you want to emulate the iOS effect, you'll probably have to do it yourself, because AFAIK the drawer component of the support library doesn't allow such type of configurations.

Anyway, every time a programmer codes a lot just to emulate some fancy (and much probably not worthy) iOS effect in Android, a little cat dies...

Share:
13,582
MCR
Author by

MCR

Updated on June 27, 2022

Comments

  • MCR
    MCR almost 2 years

    When using the drawer layout is there a way to overlay the drawer view over the action bar? I do not want to hide the action bar when the drawer is shown. I want the action bar to simply stay put, but be sent to the background. An example of this is the iOS Play Music app...

    enter image description here

    My current implementation hides and shows the action bar when the drawer state changes, but I do not like this user experience.

            public void onDrawerClosed(View view) {
                getActionBar().show();
                invalidateOptionsMenu(); 
            }
    
            public void onDrawerOpened(View drawerView) {
                getActionBar().hide();
                invalidateOptionsMenu();
            }