Android Navigation Drawer on top ActionBar
I have a tiny "trick" learnt from https://github.com/jfeinstein10/SlidingMenu to implement the effect you required.
You only need to remove the first child of the window's decor view, and add the first child to your drawer's content view. After that, you only need to add your drawer to the window's decor view.
Below is some detailed steps for you to do that.
First, create a xml named "decor.xml" or anything you like. Only put the DrawerLayout and the drawer in. The "FrameLayout" below is just a container. We will use it to wrap your activity's content.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout ...>
<FrameLayout android:id="@+id/container"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<fragment android:name="com...."
android:layout_gravity="start"
android:id="@id/navigation"
android:layout_width="@dimen/navigation_menu_width"
android:layout_height="fill_parent" />
</android.support.v4.widget.DrawerLayout>
and then remove the DrawerLayout in your main layout. Now the layout of your main activity should look like
<RelativeLayout android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
...
</RelativeLayout>
we assume that the main activity's layout is named "main.xml".
in your MainActivity, write as the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Inflate the "decor.xml"
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
DrawerLayout drawer = (DrawerLayout) inflater.inflate(R.layout.decor, null); // "null" is important.
// HACK: "steal" the first child of decor view
ViewGroup decor = (ViewGroup) getWindow().getDecorView();
View child = decor.getChildAt(0);
decor.removeView(child);
FrameLayout container = (FrameLayout) drawer.findViewById(R.id.container); // This is the container we defined just now.
container.addView(child);
// Make the drawer replace the first child
decor.addView(drawer);
// Do what you want to do.......
}
Now you've got a DrawerLayout which can slide over the ActionBar. But you might find it covered by status bar. You might need to add a paddingTop to the Drawer in order to fix that.
set navigation drawer on actionbar in android
Try removing android:fitsSystemWindows="true"
to your DrawerLayout
or making it false like android:fitsSystemWindows="false"
, probably this should work for you.
How do I use DrawerLayout to display over the ActionBar/Toolbar and under the status bar?
New functionality in the framework and support libs allow exactly this. There are three 'pieces of the puzzle':
- Using Toolbar so that you can embed your action bar into your view hierarchy.
- Making DrawerLayout
fitsSystemWindows
so that it is layed out behind the system bars. - Disabling
Theme.Material
's normal status bar coloring so that DrawerLayout can draw there instead.
I'll assume that you will use the new appcompat.
First, your layout should look like this:
<!-- The important thing to note here is the added fitSystemWindows -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/my_drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Your normal content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- We use a Toolbar so that our drawer can be displayed
in front of the action bar -->
<android.support.v7.widget.Toolbar
android:id="@+id/my_awesome_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
<!-- The rest of your content view -->
</LinearLayout>
<!-- Your drawer view. This can be any view, LinearLayout
is just an example. As we have set fitSystemWindows=true
this will be displayed under the status bar. -->
<LinearLayout
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="true">
<!-- Your drawer content -->
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
Then in your Activity/Fragment:
public void onCreate(Bundled savedInstanceState) {
super.onCreate(savedInstanceState);
// Your normal setup. Blah blah ...
// As we're using a Toolbar, we should retrieve it and set it
// to be our ActionBar
Toolbar toolbar = (...) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
// Now retrieve the DrawerLayout so that we can set the status bar color.
// This only takes effect on Lollipop, or when using translucentStatusBar
// on KitKat.
DrawerLayout drawerLayout = (...) findViewById(R.id.my_drawer_layout);
drawerLayout.setStatusBarBackgroundColor(yourChosenColor);
}
Then you need to make sure that the DrawerLayout is visible behind the status bar. You do that by changing your values-v21 theme:
values-v21/themes.xml
<style name="Theme.MyApp" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
Note:
If a <fragment android:name="fragments.NavigationDrawerFragment">
is used instead of
<LinearLayout
android:layout_width="304dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="true">
<!-- Your drawer content -->
</LinearLayout>
the actual layout, the desired effect will be achieved if you call fitsSystemWindows(boolean)
on a view that you return from onCreateView
method.
@Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View mDrawerListView = inflater.inflate(
R.layout.fragment_navigation_drawer, container, false);
mDrawerListView.setFitsSystemWindows(true);
return mDrawerListView;
}
Navigation Drawer on the top of ActionBar / StatusBar like Android 5.0 without using AppCompact / ToolBar
In a regular Activity
, the ActionBar
is part of an overlay View
that is the only direct child of the Window
's DecorView
. You can remove this child from the DecorView
, inflate the activity_main
main layout into the DecorView
, and then add the overlay View
to the DrawerLayout
's FrameLayout
, effectively putting the drawer on top of everything.
In order to avoid making changes to the BaseLogeableActivity
class, we'll need to change the ID of the DrawerLayout
's FrameLayout
, and ensure a Resource ID of container
exists to assign to the dynamically created FrameLayout
that will hold the Fragment
s.
Create the Resource ID of container
, if necessary:
<item type="id" name="container" />
Change the ID of the main layout's FrameLayout
:
<FrameLayout
android:id="@+id/overlay_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The cleanest way to add the View
juggling code is probably to just override MainActivity
's setContentView()
method, like so:
@Override
public void setContentView(int layoutResID) {
ViewGroup decorView = (ViewGroup) getWindow().getDecorView();
View overlayView = decorView.getChildAt(0);
decorView.removeView(overlayView);
getLayoutInflater().inflate(layoutResID, decorView, true);
FrameLayout overlayContainer = (FrameLayout) findViewById(R.id.overlay_container);
overlayContainer.addView(overlayView);
FrameLayout container = new FrameLayout(this);
container.setId(R.id.container);
ViewGroup content = (ViewGroup) overlayView.findViewById(android.R.id.content);
content.addView(container);
}
And finally, if you want your Activity
to cover the Status Bar, add the following attribute setting to its theme:
<item name="android:windowFullscreen">true</item>
Or, since you can't change the theme, call the following before the setContentView()
call:
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Drawer Layout on top of action bar?
You can use a ToolBar instead of the usual actionbar, the ToolBar goes as any view in your layout, like that:
<android.support.v7.widget.Toolbar
android:id=”@+id/my_toolbar”
android:layout_height=”wrap_content”
android:layout_width=”match_parent” />
And then you can set it as your action bar if you want, or deal with it directly
Navigation drawer below Actionbar
Apply this attribute to your root viewgroup android:layout_marginTop="?android:attr/actionBarSize"
. Hope this helps.
How to make the nav-drawer appear below the action bar
Just put the app bar outside the DrawerLayout
.
Code:
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:fitsSystemWindows="false"
app:headerLayout="@layout/nav_header_spellbook"
app:menu="@menu/activity_spellbook_drawer" />
</android.support.v4.widget.DrawerLayout>
<include
layout="@layout/app_bar_spellbook"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Creating a navigation drawer over action bar with header
I would use the new Toolbar instead of ActionBar. Checkout this tutorial: http://www.android4devs.com/2014/12/how-to-make-material-design-navigation-drawer.html
The important part is that you have to put the toolbar inside the DrawerLayout as seen here (activity_main.xml):
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="7dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
android:id="@+id/tool_bar"
layout="@layout/tool_bar">
</include>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World" />
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.DrawerLayout>
toolbar.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/ColorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
android:elevation="4dp"
android:paddingTop="@dimen/tool_bar_top_padding">
</android.support.v7.widget.Toolbar>
To use the toolbar:
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
setSupportActionBar(toolbar);
Related Topics
Android Options Menu Icon Won't Display
Android 2.1 View's Getdrawingcache() Method Always Returns Null
Compatiblity of Material Design to Versions Below Android 5.0
Scrolling Edittext Inside Scrollview
Ask for Password Before Uninstalling Application
Android.Os.Networkonmainthreadexception . Need to Use Async Task
How to Show Daily Offline Notifications in Android 10
How to Filter the Data in Realm Adapter
Android Spinner Error:Android.View.Windowmanager$Badtokenexception: Unable to Add Window
Ndk: How Include *.So Files in Androidstudio
Why Does Navigation Not Work in the Navigation Drawer Activity Template with Version 2.4.1
How to Animate a Slide in Notification View That Pushes the Content View Down
Sdcard Content Exist But Cant See Them
Multiple Dex Files Define Lcom/Google/Android/Gms/Internal/Zzau
Server-Side Verification of Google Play In-App Billing Version 3 Purchase