Like me, you’ve probably searched online for a navigation drawer solution that doesn’t require a third-party library. When developing apps, we’re always wary about adding extra dependencies, and in this case, the libraries available don’t even mimic all navigation drawer features.
This tutorial shows you how to modify the navigation drawer so it moves the window’s content when it opens and closes. We will modify Google’s sample app with around 10 lines of code to add this functionality.
Begin by loading the sample app. We’ll add code directly to these files to illustrate the technique.
Since the action bar will be moving over when the drawer opens and closes, the drawer needs to claim the area under the action bar. This is achieved by making the action bar an overlay so the window lays out the content to its full height. Any changes to the code are highlighted in yellow. Set the window’s flag inside the Activity.java file. It must happen before super.onCreate() and can alternatively be set in the manifest.xml, if you prefer.
The obvious drawback of the action bar overlay is that it now overlaps the window’s content. While we want the drawer to extend the height of the window, we still want the other content to fit below the action bar. To make it look normal again, set a top padding on the layout. I prefer keeping a ‘host’ layout with this setting and then adding and removing child layouts with ‘match parent’ attributes. activity_main.xml will look something like this (modified from the Google sample project):
In order to be notified when the drawer is moving, and how far it has moved, add a callback method from the Android API. The sample app illustrates onDrawerOpen() and onDrawerClosed() but there are additional methods available. Add the onDrawerSlide() method in MainActivity.java within the anonymous class defined by ‘mDrawerToggle’. This portion of the file will then look like this, with the added changes in bold:
To know where to put the window’s content, we can find the visible width of the drawer by treating ‘slideOffset’ as a percentage. The edge of the drawer is the x-location for the window’s content.
There are two things to move with the drawer: the layout and the action bar. To move the layout, create a reference in MainActivity to the FrameLayout (i.e., ‘content_frame’) defined in activity_main.xml. For example:
mHostFragment = findViewById(R.id.content_frame);
Then we can change its position during drawer movement.
The final ingredient is to move the action bar. This requires accessing its associated view, which unfortunately is not straightforward, but is simple enough. This helper method within MainActivity does the trick on 4.0 and above:
Now the action bar can be moved with the content:
The notable modifications are overriding onDrawerSlide() and making the action bar an overlay. Notice that providing v7 support requires changing the call name of some methods. In development, you can put all this logic into its own Fragment class outside the activity. In doing this, you would also move the ListView in activity_main (‘left_drawer’) into the new fragment, and replace it with a reference. activity_main.xml will then look something like this: