Android Navigation Drawer and windowActionBarOverlay = true

25,487

Solution 1

In case anyone is interested in another take to this question. Here's what happened.

I tried setting only the margin to the top of the list view like this:

android:layout_marginTop="?android:attr/actionBarSize"

But as mentioned on the edited question, that had a weird behaviour where there was also a margin on the bottom despite not being set on the layout resource file.

So, I was looking closely at the Play Music App and noticed that it's not actually a margin, but rather some padding, and additionally they are using a custom background that fills the space specified by the padding with a transparent color.

Here's what I did:

  • Set Padding at the top of the ListView, rather than margin:

    android:paddingTop="?android:attr/actionBarSize"

As said before, it's important to not hard code the dimensions as they vary per device.

  • Create a custom drawable that has a top part transparent, and then rest of a solid color:

It looks somehow like this:

<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
    <shape  android:shape="rectangle">
        <solid android:color="#80000000" />
    </shape>
</item>

<item android:top="@dimen/action_bar_default_height">
    <shape
            android:shape="rectangle">
        <solid android:color="@color/light_gray" />
    </shape>
</item>

Note that I tried to use ?android:attr/actionBarSize on the drawable, but that made the app force close. Instead, I searched through grepcode and found a few dimen files with different sizes for the action bar, so I added those to my own project's dimen files.

  • For values: 48dp
  • For values-land: 40dp
  • For values-sw600dp: 56dp

And after that, I think I looks great, notice on the screenshot how the listview and the actionbar don't overlap, and the transparent part of the listview is just the right size.

enter image description here

Hope that helps anyone who was wondering how to achieve this.

Solution 2

And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.

If you set your ListView gravity to start|bottom it solves your problem. No additional margin is added at the bottom. Looks like the DrawerLayout default gravity is start|center

<ListView
    android:id="@+id/left_drawer"
    android:layout_marginTop="?android:attr/actionBarSize"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start|bottom"/>

Solution 3

You can set a margin at the top of your layout, so that the content draws itself below the ActionBar.

Just add this in your parent layout:

android:layout_marginTop="?android:attr/actionBarSize"

The attribute actionBarSize refers to, like you would have already guessed, to the size of the ActionBar. You can't set an absolute value as a margin, since the ActionBar does not always have the same size across all Android devices (It's bigger on tablets, smaller on handset devices).

Edit:

Set the margin to the ListView.

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <ListView
        android:id="@+id/left_drawer"
        android:layout_marginTop="?android:attr/actionBarSize"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>

The Google Music app does the same:

enter image description here

Solution 4

I solved this problem using paddingTop:

<FrameLayout
    android:id="@+id/menu_frame"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:paddingTop="?attr/actionBarSize" >

    <ListView 
        android:id="@+id/left_drawer_list"
        android:layout_width="240dp"
        android:layout_height="match_parent" />

</FrameLayout>

Hope that helps

Share:
25,487

Related videos on Youtube

daniel_c05
Author by

daniel_c05

Updated on July 23, 2022

Comments

  • daniel_c05
    daniel_c05 almost 2 years

    I'm trying to implement the new Android Navigation Drawer in my application. I have created a BaseActivity.java that handles the Drawer setup and listeners, and I have two subactivities that extend this base class. On the second activity, I plan to use a different action bar style, using the following attrs:

    <item name="android:windowActionBarOverlay">true</item>
    <item name="android:background">@android:color/transparent</item>
    

    to make the action bar transparent, and make content richer, as there is a picture header in my layout.

    I've achieved just that, but now the problem is, that because the content is expanding to take advantage of the extra space of using the ActionBar as overlay, the Navigation Drawer itself is expanding too and it overlaps the ActionBar, creating a pretty awful looking layout:

    enter image description here

    What I'd like to have done, is the actual content (frame layout that will be populated with a fragment) to take up the extra space, but have the nav drawer still go underneath the action bar, similar to the Play Music App:

    enter image description here

    Any ideas on what I can do to make that happen?

    EDIT So, as per Ahmad's assistance I set the marginTop on the ListView only. Here's the layout:

    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
              android:layout_marginTop="?android:attr/actionBarSize"
    <!-- This was added after seeing the crazy effect, but does nothing -->
              android:layout_marginBottom="0dp"
              android:layout_marginLeft="0dp"
              android:layout_marginRight="0dp"
              android:layout_width="240dp"
              android:layout_height="fill_parent"
              android:layout_gravity="start"
              android:choiceMode="singleChoice"
              android:background="?attr/listviewBackground"
              />
    

    And now, it works great for the top side, but for some reason there's also a margin at the bottom of the view, which doesn't make any sense to me at all. Here's a screenshot.

    Not sure what's causing it :(

  • daniel_c05
    daniel_c05 almost 11 years
    Wouldn't that also set the margin for the frame layout? and therefore making the fragment's content be displayed below the action bar?
  • Ahmad
    Ahmad almost 11 years
    Yes this would place everything below the ActionBar
  • daniel_c05
    daniel_c05 almost 11 years
    Exactly, and that'd pose a problem since I expect the content to take advantage of the transparency of the actionbar, that's why I'm using the overlay to begin with. I only want the drawer to be below the actionbar.
  • daniel_c05
    daniel_c05 almost 11 years
    Hey Ahmad, would you mind looking at the edited question? Thanks!
  • Ahmad
    Ahmad almost 11 years
    @daniel_c05 sorry was offline. But it seems like you already solved the problem.
  • ebernie
    ebernie about 10 years
    I tried your solution but couldn't make it work. Is the background set to the listview?
  • Steve Luck
    Steve Luck over 8 years
    Where did you implement that "Create a custom drawable that has a top part transparent, and then rest of a solid color" ?