androidandroid-activitynavigationnavigation-drawerdrawer

Same Navigation Drawer in different Activities


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

Solution

  • 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 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() ;
    }