Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DrawerLayout on top of Actionbar

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();
        }
like image 870
MCR Avatar asked Feb 19 '14 15:02

MCR


People also ask

How do you use DrawerLayout?

To use a DrawerLayout, position your primary content view as the first child with width and height of match_parent and no layout_gravity> . Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.

What is the purpose of DrawerLayout and Navigationview?

Drawer Layout is the root layout in which we define a FrameLayout and a Navigation View. In Navigation View we set the items from menu file and FrameLayout is used to replace the Fragments on the click of menu items.

What is the purpose of an ActionBar?

In Android applications, ActionBar is the element present at the top of the activity screen. It is a salient feature of a mobile application that has a consistent presence over all its activities. It provides a visual structure to the app and contains some of the frequently used elements for the users.


3 Answers

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!

like image 64
Andranik Avatar answered Sep 22 '22 21:09

Andranik


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

like image 44
thelawnmowerman Avatar answered Sep 21 '22 21:09

thelawnmowerman


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.

like image 29
Submersed Avatar answered Sep 25 '22 21:09

Submersed