Same Navigation Drawer in different Activities

245,752

Solution 1

If you want a navigation drawer, you should use fragments. I followed this tutorial last week and it works great:

http://developer.android.com/training/implementing-navigation/nav-drawer.html

You can also download sample code from this tutorial, to see how you can do this.


Without fragments:

This is your BaseActivity Code:

public class BaseActivity extends Activity
{
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    public String[] layers;
    private ActionBarDrawerToggle drawerToggle;
    private Map map;

    protected void onCreate(Bundle savedInstanceState)
    {
        // R.id.drawer_layout should be in every activity with exactly the same id.
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);

        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) 
        {
            public void onDrawerClosed(View view) 
            {
                getActionBar().setTitle(R.string.app_name);
            }

            public void onDrawerOpened(View drawerView) 
            {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        layers = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        View header = getLayoutInflater().inflate(R.layout.drawer_list_header, null);
        drawerList.addHeaderView(header, null, false);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text1,
                layers));
        View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(
                R.layout.drawer_list_footer, null, false);
        drawerList.addFooterView(footerView);

        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                map.drawerClickEvent(pos);
            }
        });
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
}

All the other Activities that needs to have a navigation drawer should extend this Activity instead of Activity itself, example:

public class AnyActivity extends BaseActivity
{
    //Because this activity extends BaseActivity it automatically has the navigation drawer
    //You can just write your normal Activity code and you don't need to add anything for the navigation drawer
}

XML

<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">
    <!-- The main content view -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <!-- Put what you want as your normal screen in here, you can also choose for a linear layout or any other layout, whatever you prefer -->
    </FrameLayout>
    <!-- The navigation drawer -->
    <ListView android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.DrawerLayout>

Edit:

I experienced some difficulties myself, so here is a solution if you get NullPointerExceptions. In BaseActivity change the onCreate function to protected void onCreateDrawer(). The rest can stay the same. In the Activities which extend BaseActivity put the code in this order:

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
    super.onCreateDrawer();

This helped me fix my problem, hope it helps!

This is how you can create a navigation drawer with multiple activities, if you have any questions feel free to ask.


Edit 2:

As said by @GregDan your BaseActivity can also override setContentView() and call onCreateDrawer there:

@Override 
public void setContentView(@LayoutRes int layoutResID) 
{ 
    super.setContentView(layoutResID); 
    onCreateDrawer() ;
}

Solution 2

I've found the best implementation. It's in the Google I/O 2014 app.

They use the same approach as Kevin's. If you can abstract yourself from all unneeded stuff in I/O app, you could extract everything you need and it is assured by Google that it's a correct usage of navigation drawer pattern. Each activity optionally has a DrawerLayout as its main layout. The interesting part is how the navigation to other screens is done. It is implemented in BaseActivity like this:

private void goToNavDrawerItem(int item) {
        Intent intent;
        switch (item) {
            case NAVDRAWER_ITEM_MY_SCHEDULE:
                intent = new Intent(this, MyScheduleActivity.class);
                startActivity(intent);
                finish();
                break;

This differs from the common way of replacing current fragment by a fragment transaction. But the user doesn't spot a visual difference.

Solution 3

Easiest way to reuse a common Navigation drawer among a group of activities

app_base_layout.xml

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

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

    </FrameLayout>

    <android.support.design.widget.NavigationView
        android:id="@+id/navigation_view"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/menu_test"
        />
</android.support.v4.widget.DrawerLayout>

AppBaseActivity.java

/*
* This is a simple and easy approach to reuse the same 
* navigation drawer on your other activities. Just create
* a base layout that conains a DrawerLayout, the 
* navigation drawer and a FrameLayout to hold your
* content view. All you have to do is to extend your 
* activities from this class to set that navigation 
* drawer. Happy hacking :)
* P.S: You don't need to declare this Activity in the 
* AndroidManifest.xml. This is just a base class.
*/
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.design.widget.NavigationView;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public abstract class AppBaseActivity extends AppCompatActivity implements MenuItem.OnMenuItemClickListener {
    private FrameLayout view_stub; //This is the framelayout to keep your content view
    private NavigationView navigation_view; // The new navigation view from Android Design Library. Can inflate menu resources. Easy
    private DrawerLayout mDrawerLayout;
    private ActionBarDrawerToggle mDrawerToggle;
    private Menu drawerMenu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        super.setContentView(R.layout.app_base_layout);// The base layout that contains your navigation drawer.
        view_stub = (FrameLayout) findViewById(R.id.view_stub);
        navigation_view = (NavigationView) findViewById(R.id.navigation_view);
        mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout, 0, 0);
        mDrawerLayout.setDrawerListener(mDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        drawerMenu = navigation_view.getMenu();
        for(int i = 0; i < drawerMenu.size(); i++) {
          drawerMenu.getItem(i).setOnMenuItemClickListener(this);
        }
        // and so on...
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        mDrawerToggle.syncState();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    /* Override all setContentView methods to put the content view to the FrameLayout view_stub
     * so that, we can make other activity implementations looks like normal activity subclasses.
     */
    @Override
    public void setContentView(int layoutResID) {
        if (view_stub != null) {
            LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            View stubView = inflater.inflate(layoutResID, view_stub, false);
            view_stub.addView(stubView, lp);
        }
    }

    @Override
    public void setContentView(View view) {
        if (view_stub != null) {
            ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.MATCH_PARENT,
                    ViewGroup.LayoutParams.MATCH_PARENT);
            view_stub.addView(view, lp);
        }
    }

    @Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        if (view_stub != null) {
            view_stub.addView(view, params);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Pass the event to ActionBarDrawerToggle, if it returns
        // true, then it has handled the app icon touch event
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        // Handle your other action bar items...

        return super.onOptionsItemSelected(item);
    }

    @Override
    public boolean onMenuItemClick(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.item1:
                // handle it
                break;
            case R.id.item2:
                // do whatever
                break;
            // and so on...
        }
        return false;
    }
}

Solution 4

So this answer is a few years late but someone may appreciate it. Android has given us a new widget that makes using one navigation drawer with several activities easier.

android.support.design.widget.NavigationView is modular and has its own layout in the menu folder. The way that you use it is to wrap xml layouts the following way:

  1. Root Layout is a android.support.v4.widget.DrawerLayout that contains two children: an <include ... /> for the layout that is being wrapped (see 2) and a android.support.design.widget.NavigationView.

    <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/drawer_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true"
        tools:openDrawer="start">
    
    <include
        layout="@layout/app_bar_main"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    
    <android.support.design.widget.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_header_main"
        app:menu="@menu/activity_main_drawer" />
    

nav_header_main is just a LinearLayout with orientation = vertical for the header of your Navigation Drawar.

activity_main_drawer is a menu xml in your res/menu directory. It can contain items and groups of your choice. If you use the AndroidStudio Gallery the wizard will make a basic one for you and you can see what your options are.

  1. App bar layout is usually now a android.support.design.widget.CoordinatorLayout and this will include two children: a android.support.design.widget.AppBarLayout (which contains a android.support.v7.widget.Toolbar) and an <include ... > for your actual content (see 3).

    <android.support.design.widget.CoordinatorLayout
        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:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="yourpackage.MainActivity">
    
     <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">
    
        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    
    </android.support.design.widget.AppBarLayout>
    
    <include layout="@layout/content_main" />
    

  2. Content layout can be whatever layout you want. This is the layout that contains the main content of the activity (not including the navigation drawer or app bar).

Now, the cool thing about all of this is that you can wrap each activity in these two layouts but have your NavigationView (see step 1) always point to activity_main_drawer (or whatever). This means that you will have the same(*) Navigation Drawer on all activities.

  • They won't be the same instance of NavigationView but, to be fair, that wasn't possible even with the BaseActivity solution outlined above.

Solution 5

For anyone else looking to do what the original poster is asking, please consider to use fragments instead the way Kevin said. Here is an excellent tutorial on how to do that:

https://github.com/codepath/android_guides/wiki/Fragment-Navigation-Drawer

If you choose to instead use activities instead of fragments you are going to run into the problem of the nav drawer being re-created every time you navigate to a new activity. This results in an ugly/slow rendering of the nav drawer each time.

Share:
245,752

Related videos on Youtube

MEX
Author by

MEX

Updated on November 03, 2021

Comments

  • MEX
    MEX over 2 years

    I made a working navigation drawer like it's shown in the tutorial on the developer.android.com website. But now, I want to use one Navigation Drawer, i created in the NavigationDrawer.class for multiple Activities in my Application.

    My question is, if anyone here can make a little Tutorial, which explains, how to use one Navigation drawer for multiple Activities.

    I read it first at this Answer Android Navigation Drawer on multiple Activities

    but it didn't work on my Project

    public class NavigationDrawer extends Activity {
    public DrawerLayout drawerLayout;
    public ListView drawerList;
    private ActionBarDrawerToggle drawerToggle;
    
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) {
    
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(R.string.app_name);
            }
    
            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(R.string.menu);
            }
        };
        drawerLayout.setDrawerListener(drawerToggle);
    
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);
    
        listItems = getResources().getStringArray(R.array.layers_array);
        drawerList = (ListView) findViewById(R.id.left_drawer);
        drawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, android.R.id.text,
                listItems));
        
        drawerList.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> arg0, View arg1, int pos, long arg3) {
                drawerClickEvent(pos);
            }
        });
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    
        if (drawerToggle.onOptionsItemSelected(item)) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    
    }
    
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        drawerToggle.onConfigurationChanged(newConfig);
    }
    }
    

    In this Activity i want to have the Navigation Drawer so I extends 'NavigationDrawer' and in some other Activities i want to User the Same Navigation drawer

      public class SampleActivity extends NavigationDrawer {...}
    
  • MEX
    MEX over 10 years
    I Made a working Navigation drawer, but now I want to Use one Navigation drawer in multiple activities
  • Kevin van Mierlo
    Kevin van Mierlo over 10 years
    The way to go is to use fragments instead of activities. I can't think of any reason why you want to use activities over fragments.
  • MEX
    MEX over 10 years
    I don't want to use activitys over fragments, I just want to use different activitys which uses all the same navigation drawer. I want activity, because there I can use different types of layout like swipe view, map view...
  • slott
    slott over 10 years
    Having just one Activity can be a daunting task for any fairly complex app. Using Activities gives you a lot of free things from the system - so it is a valid point how to use multiple Activities. I can't imagine one Activity handling communication between any number of fragment combinations - it's just not gonna work.
  • Kevin van Mierlo
    Kevin van Mierlo over 10 years
    I'm sorry it took so long for me to answer. I Edited my answer. I believe this is the tutorial you were looking for. Hope this helps.
  • Rishabh Srivastava
    Rishabh Srivastava over 10 years
    do not know why this answer was accepted but extending main class does not do the task. It does not slide out.
  • Kevin van Mierlo
    Kevin van Mierlo over 10 years
    @RishabhSrivastava I don´t know what you did, but you did something wrong. This worked for me and for Mex and probably more people. Did you follow my tutorial correctly? You have to write an activity class: BaseActivity. And the Activity classes you want in your app need to extend BaseActivity. Thats all there is to it.
  • Rishabh Srivastava
    Rishabh Srivastava over 10 years
    Ok it worked but the list set in the baseactivity does not show up here in AnyActivity....why?
  • Kevin van Mierlo
    Kevin van Mierlo over 10 years
    Make a new question and link me to it. I need to see your code.
  • Loolooii
    Loolooii about 10 years
    @KevinvanMierlo can you tell me what you mean by: R.id.drawer_layout should be in every activity with exactly the same id. Because I did exactly what you told here and I get a NullPointerException in onCreate() method of the Activity that extends this BaseActivity..
  • Kevin van Mierlo
    Kevin van Mierlo about 10 years
    @Loolooii You make a drawerlayout in the layout file of your activity and you give this the id "drawer_layout"
  • Loolooii
    Loolooii about 10 years
    @KevinvanMierlo I do exactly that and I think it should work now, but it doesn't. When I click on the drawer icon the drawer does not show. I don't get any errors whatsoever. Do you know why?
  • Loolooii
    Loolooii about 10 years
    @KevinvanMierlo btw, I think you forgot these 2 lines? super.onCreate(savedInstanceState); setContentView(R.layout.activity_base);
  • Loolooii
    Loolooii about 10 years
    @KevinvanMierlo how do I keep the layout of my activity and add this drawerLayout into that? Because both activities require me to set a contentView.. And the layout of my activity overrides the layout of the drawer. Can you explain that part please?
  • Kevin van Mierlo
    Kevin van Mierlo about 10 years
    OK, create a new question and link that question to me or put your code online and link that to me. I don't know whats not working untill I see your code.
  • Yugesh
    Yugesh about 10 years
    @KevinvanMierlo How can i move from one activity to another while i click the item in Drawer list
  • Kevin van Mierlo
    Kevin van Mierlo about 10 years
    @Yugesh set setOnItemClickListener on drawerList and from there start your new activity (Intent myIntent = new Intent(CurrentActivity.this, NextActivity.class); CurrentActivity.this.startActivity(myIntent);)
  • user1627990
    user1627990 about 10 years
    Hi Kevin, I've followed your instructions and it's crashing. I've posted a question, I'd appreciate a lot if you could help me out! :) stackoverflow.com/questions/22137283/…
  • Lion789
    Lion789 about 10 years
    What if you are extending a fragmentActivity for a viewpager already, how do you go about implementing this... I was originally just including the same code in both my Home activity and my other activity, the problem is that from my other activity with the viewpager I could not click on any items - is that an issue that can be fixed or try to use this method but in that case how to implement it?
  • Kevin van Mierlo
    Kevin van Mierlo about 10 years
    @Lion789 I think if you want that your base activity needs to extend fragmentActivity or else nothing will work. For the rest I'm not sure if something could cause issues. If you still have issues, make a question and link me to it, cause then I need to see some code.
  • theblang
    theblang almost 10 years
    @slott I am trying to do just that, a single activity architecture. I definitely feel that I am getting bogged down. The dilemma, though, is that fragments load in so much faster than launching new activities.
  • slott
    slott almost 10 years
    Loads faster than launching new activities ??? - You must be doing something wrong. Any activity should start instantly and then you do the heavy lifting using background tasks while showing a spinner or whatever makes sense for your app. I've made countless apps and never had problems with slow activities.
  • Shumail
    Shumail almost 10 years
    @KevinvanMierlo : Just a quesiotn, for implementing navigation drawer as i understood - Am i supposed to have only one activity and all other as fragments in my whole app ?
  • Kevin van Mierlo
    Kevin van Mierlo almost 10 years
    @ShumailMohy-ud-Din That is recommended by google. But as slott said, if you have a complex app this might not be the right way. For smaller apps one activity and only fragments should be fine.
  • Shumail
    Shumail almost 10 years
    @KevinvanMierlo Thankyou - Yeah for complex that's seriously a mess. I am trying to do with activities
  • Price
    Price over 9 years
    @KevinvanMierlo Can you please post the XML layout for BaseActivity and AnyActivity? That would be very helpful!
  • Kevin van Mierlo
    Kevin van Mierlo over 9 years
    @user87049 XML layout added. BaseActivity doesn't have a layout. Just make sure to add drawer_layout in every activity and extend BaseActivity in every Activity.
  • levi
    levi over 9 years
    Can we make it without the same XML in every Activity layout?
  • Kevin van Mierlo
    Kevin van Mierlo over 9 years
    @levi Yeah, the drawer layout part and the listview part should be in every activity. The framelayout can be any layout you want and this is the layout for your screen. You can change this in the way you like
  • Kurt Wagner
    Kurt Wagner over 9 years
    @KevinvanMierlo I'm using Android Studio and pasted the BaseActivity code, but am running up against symbols not being able to be resolved such as ic_drawer, menu, layers_array, drawer_list_header, drawer_list_item, drawer_list_footer, and the drawerClickEvent() as well If the BaseActivity doesn't require a layout how do I resolve these errors?
  • Kevin van Mierlo
    Kevin van Mierlo over 9 years
    @KurtWagner This BaseActivity was specific for the question, here is the code for everybody to use: gist.github.com/kevinvanmierlo/c1a0d6b8bed65b1eeaa6 ic_drawer is an icon provided in the actionbar pack: developer.android.com/downloads/design/Android_Design_Icons_‌​20130926.zip (ic_drawer is the image, three stripes, next to the logo if a navigation drawer is available)
  • M S Gadag
    M S Gadag over 9 years
    @KevinvanMierlo drawer layout is appering only by dragging.. on click image is not working... and list is not visible.
  • Kevin van Mierlo
    Kevin van Mierlo over 9 years
    @MSGadag I'm not sure why list is not visible, but for the on click image check this: developer.android.com/training/implementing-navigation/… This is from the android website that walks you through how to get the on click on a drawerlayout. If you can't manage to make the list working create a new question and link me to that question, I will help you
  • Nick H
    Nick H about 9 years
    This ^ I cant figure out how they start new activities and it works flawlessly. It's a large app to work through.
  • Joaquin Iurchuk
    Joaquin Iurchuk almost 9 years
    @hitch.united That's because they use a lot of fragments and just a few activities.
  • EpicPandaForce
    EpicPandaForce almost 9 years
    @hitch.united they probably override the animation of the activity with overridePendingTransitions.
  • David
    David almost 9 years
    @slott I don't agree with you. this is not about communication between activities. this is inheritance. all of activities and it's components even naviagation drawer is alive but with a same parent.
  • Hamed MP
    Hamed MP almost 9 years
    @KevinvanMierlo Can you please post snippet of main_activity.xml too? Thanks!
  • Kevin van Mierlo
    Kevin van Mierlo almost 9 years
    @HamedMP The xml is the post snippet of main_activity.xml. In the FrameLayout (content_frame) you put your normal layout. I just stripped that because it's irrelevant for the answer. Just to be clear, the BaseActivity doesn't have an xml file.
  • Greg Dan
    Greg Dan over 8 years
    Better solution is to @Override public void setContentView(@LayoutRes int layoutResID) { super.setContentView(layoutResID); onCreateDrawer() }
  • Kevin van Mierlo
    Kevin van Mierlo over 8 years
    @GregDan Good solution! Added it to my answer.
  • Sharath
    Sharath over 8 years
    It works good.I have a doubt.Actually should we add drawer layout and listview in the child activity's layout also?
  • Kevin van Mierlo
    Kevin van Mierlo over 8 years
    @Sharanth yes those layouts should be added to the child activity. You could put the list view in a separate layout or make the drawer a fragment so you don't have to add everything everything you want an activity with a drawer
  • syloc
    syloc over 8 years
    @slott You can use EventBus for all your communications.
  • slott
    slott over 8 years
    Yes EventBus is a real game changer when it comes to communication across fragments and activities.
  • Pau Arlandis Martinez
    Pau Arlandis Martinez about 8 years
    I try to use this solution but I have a problem on this line: drawerToggle = new ActionBarDrawerToggle((Activity) this, drawerLayout, R.drawable.ic_drawer, 0, 0) where AS says it is specting a toolbar on the third parameter and R.drawable.ic_drawer is an int. How can I solve it?
  • Kevin van Mierlo
    Kevin van Mierlo about 8 years
    @PauArlandisMartinez The new ActionBarDrawerToggle doesn't need a drawable anymore, so you have two options: Use the ActionBarDrawerToggle with an ActionBar or with a Toolbar. Example using ActionBar: drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, 0, 0);. Example with Toolbar: drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, 0, 0);. The two zeros on the end should be a String located in the strings.xml.
  • Pau Arlandis Martinez
    Pau Arlandis Martinez about 8 years
    @KevinvanMierlo ok, but if I use the actionBar solution I need to import android.support.v4.app.ActionBarDrawerToggle and If I use the toolbar solution I need to import android.support.v7.app.ActionBarDrawerToggle. It's important to have this in mind. Also the actionBar solution is deprecated today.
  • Kevin van Mierlo
    Kevin van Mierlo about 8 years
    @PauArlandisMartinez No you should use android.support.v7.app.ActionBarDrawerToggle. You can leave out toolbar and I think it should work then. But the ActionBar in general is deprecated now, so you should think about the Toolbar solution.
  • Pihu
    Pihu almost 8 years
    sir, i used the same with extending BaseActivity but on back pressed this navigation doesn't work. Please help
  • Kevin van Mierlo
    Kevin van Mierlo almost 8 years
    @PriyankaMinhas Can you create a new question? I don't want to overload this answer with comments. In that question you could give me some more details and the code you're using.
  • Pihu
    Pihu almost 8 years
  • Abhinav Saxena
    Abhinav Saxena almost 8 years
    This is an older post. You can use fragments to ensure you have one activity always. You keep replacing the fragments in one container dedicated to it. Put in back stack when you need backward navigation, or pop all the fragments when you need a fragment to be shown as the first one.
  • justinraczak
    justinraczak over 7 years
    @KevinvanMierlo I get null pointer exceptions when the onCreateDrawer method tries to operate on the drawer. Because the drawer xml is in the layout of the base activity (dashboard activity in my case), it isn't available in subsequent activities extending the base activity. How should the XML be arranged? I was going to abstract the drawer into a separate layout file but based on how the drawer needs to wrap the rest of the content I'm not sure how to accomplish that.
  • justinraczak
    justinraczak over 7 years
    @KevinvanMierlo I created a separate question here: stackoverflow.com/questions/39878380/…
  • Denny
    Denny over 7 years
    Where are you using content_frame?
  • Kevin van Mierlo
    Kevin van Mierlo over 7 years
    @Denny content_frame is the regular layout you normally put the screen in. So if you want to show an image on that page you need to put the ImageView inside the content_frame. It could also be another layout, it's just to clarify that the regular layout should be there.
  • CoolMind
    CoolMind over 7 years
    After many bugs and difficult situations with fragments I understood that it should better use activities with Navigation drawer. Keyboard events, transparent statusbar, data transfer between fragments and so on. Don't use fragments!
  • CoolMind
    CoolMind over 7 years
    Some people write that activity with fragments creates new fragments faster, also an animation is more friendly (with activities you should create a new activity and then close a drawer). Also I encountered a difficult bug with creating and managing menus. Then I returned to fragments, as they already work :(
  • Kevin van Mierlo
    Kevin van Mierlo over 7 years
    @CoolMind You're right that fragments responds quicker and has more possibilities with animation. But in the end, if you create this code once you can reüse it for every project you have with a NavigationDrawer. Creating menus should be the same as always
  • CoolMind
    CoolMind over 7 years
    @KevinvanMierlo, thanks. First I tried to make with fragments as recommended, but I need different toolbars at different fragments ((a) usual ActionBars and (b) an image from top, behind transparent Statusbar). A similar topic: stackoverflow.com/questions/35015182/…. I made one activity with DrawerLayout and NavigationView, having Toolbar and other stuff in fragment. It works not always correctly, especially on new Androids.
  • CoolMind
    CoolMind over 7 years
    Then I tried to replace with activities and got a problem when tried to replace a toolbar. onCreateOptionsMenu stopped adding menu buttons, onOptionsItemSelected stopped to be called. So many difficult situations, that I returned to fragments again.
  • Kevin van Mierlo
    Kevin van Mierlo over 7 years
    @CoolMind If it does not always work correctly, I don't really know what's going on. You could create another question for that. onCreateOptionsMenu is probably not called because you haven't done setSupportActionBar with the Toolbar. If this isn't the case you should also create another question.
  • CoolMind
    CoolMind over 7 years
    @KevinvanMierlo, you are right, better create another question. Also will try your code for activities creation. Thanks!
  • Vikas Pandey
    Vikas Pandey almost 7 years
    is Loading fragments instead of subclassing activities?
  • jwehrle
    jwehrle over 6 years
    stackoverflow is cutting off some of the enclosing xml brackets but the important stuff is all there.
  • denvercoder9
    denvercoder9 over 6 years
    Here's the file from October 2014: github.com/google/iosched/blob/…
  • davoid
    davoid over 6 years
    I wanted to try your solution but I get this error: "This Activity already has an action bar supplied by the window decor". I want to switch between 3 activities and each other has its own app bar. Do you think that is possible ?
  • Pavlus
    Pavlus over 6 years
    I think, you need to move your actionbar to fragments in that case. In our app we used NoActionBar theme and provided toolbar for compatibility, as far as i remember.
  • Abhinav Saxena
    Abhinav Saxena almost 6 years
    @Cabuxa.Mapache Please check the attached link to my answer for getting further assistance. I have taken a common BaseActivity, which helps sharing ActionBar ToolBar and NavigatonDrawer and other components in all the fragments attached to it.
  • Craig P
    Craig P over 5 years
    @Pavlus what would the code look like on the second activity? class trackActivity : BaseAppCompatActivity(){ ?
  • Ashik Azeez
    Ashik Azeez over 5 years
    Cannot resolve method protected void onCreateDrawer() in Base activity extend from Activity
  • Kevin van Mierlo
    Kevin van Mierlo over 5 years
    @AshikAzeez You need to create this method yourself. In the first part of my answer you'll see all drawer related code in the onCreate, but because that gave exceptions I moved the code to a method onCreateDrawer().
  • Tejas Pandya
    Tejas Pandya about 5 years
    @KevinvanMierlo i've place original content inside framelayout . now when i replace it with fragment its overlap to eachother . any workarround ?
  • Kevin van Mierlo
    Kevin van Mierlo about 5 years
    @TejasPandya I don't really know what you mean, but I guess you should replace the fragments so it doesn't overlap and also remove the original view (which is now inside your fragment
  • Laur89
    Laur89 about 5 years
    but how do you treat functionality like buttons? you must write the same code in every activity?
  • jwehrle
    jwehrle about 5 years
    Yes, because these are separate instances. However, you can make a super class for your activities to extend and put that code there once.
  • Joe Lapp
    Joe Lapp almost 5 years
    I found this awesome page for getting a Kotlin fragment solution going in a hurry. You just need to change fragmentManager to supportFragmentManager and add android:id="@+id/content_main" to the content_main.xml layout. All of the changes to the generated template are in onNavigationItemSelected(). You'll need to modify it to use the back stack. javaant.com/android-navigation-drawer-using-fragment-and-kot‌​lin/…
  • ekashking
    ekashking almost 5 years
    It's all true with just one BIG problem. Fragments suck in almost every way, especially how they slide in and out. Absolutely NO beauty and STABILITY in that process, a possibility for double-clicking the links, etc.
  • CDrosos
    CDrosos almost 4 years
    @jwehrle can you write an example about making a super class for our activities?
  • CDrosos
    CDrosos almost 4 years
    Can you provide an example of an activity that uses this base activity?
  • Levon Petrosyan
    Levon Petrosyan almost 4 years
    Can't actually remember any details on this, I think just extending AppBaseActivity and setContentView ind default way should work.
  • jwehrle
    jwehrle almost 4 years
    public abstract class MyBaseActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { // implement the following: Override public boolean onNavigationItemSelected(@NonNull MenuItem item) {} } public class MyActivity extends MyBaseActivity {}
  • jwehrle
    jwehrle almost 4 years
    The formatting is all wrong in the comment section. Define a base class for yourself that extends Activity (in this case, AppCompatActivity) and then all of your regular activities should extend your new base activity. Essentially, you are inserting a class in between your activities and Android's activity class.