DesignLibrary / DrawerLayout / Material Design / NavigationView

Design Library – Part 1

At Google I/O 2015 the Material Design Support Library was announced, and with it creating material apps targeting API levels below API 19 suddenly got a lot easier. In this series we’ll look at taking the RSS Reader app that we used as a basis for the Material series, and re-write it to make full use of the new Design Support Library.

Although we’re going to re-write the earlier app, that only really applies to the UI layer – we’re going to re-use the RSS retrieval and parsing code (so I won’t bother explaining it here). However, we’re going to modify the data model slightly to facilitate a new navigation model that we’re going to use in this app. The basic idea is that the Navigation Drawer will contain a list of articles – each article is composed of the individual parts (which have been published as individual blog posts). When an article is selected, a ViewPager will be set up with each page within the ViewPager holding a separate part. So we need a couple of new classes:

This represents each article. Note the use of a SparseArray here. The reason for this is that the RSS feed returns the last 10 published articles, so we are not guaranteed to receive all of the posts in each article. By using a SparseArray we can cope with a set of articles which does not start at the first post.

The other class represents a group of articles and is responsible for parsing these from the existing Feed object:

The basic principle here is that each article has a title of the form “My Title – Part x” and we use a regular expression to extract the base title (i.e. “My Title” in the example) and the part number (i.e. “x” in the example) and create a list of Article objects and a sorted list of title Strings which can be queried externally.

There are some standard colours and strings which I’ve created in resources, but let’s take a quick look at our app theme:

We’ve extended a standard “NoActionBar” AppCompat theme but we’re going to use an ActionBar in the app. The reason for choosing this theme is that we’re going to use our own Toolbar implementation in our layout, so we don’t want the system to create an ActionBar for us. The other thing worth noting is that we declare a base theme which is used as the parent of our main theme which doesn’t override anything. The reason for this is that we need to add some additional attributes on Lollipop and later devices so we’re defining a common base:

This gives us a transparent status bar on Lollipop and later.

Next let’s take a look at our main activity layout:

This defines a DrawerLayout, the container within which both the NavigationView and the main layout live.

It is possible to specify a menu resource on NavigationView which can display a static navigation menu and is a simple yet powerful way of implementing static menus. However our menu items will be determined by the content of the RSS feed, so we’ll need to do this programatically later on.

The NavigationView also specifies a headerLayout which will be used as the header above the navigation list. Typically this could hold user information, but in our case we’ll just hold a static Styling Android identifier as all of the content is from a Styling Android RSS feed:

The other layout included in the activity layout is include_main:

This is pretty simple for now – we’ll add to it later. It contains our Toolbar with the background colour set to the primary colour from our theme, and with an appropriate ActionBar theme applied.

We have a couple of classes which link the Activity to the data – DataFragment (which was discussed in depth in Material – Part 1) and ArticlesConsumer which is the equivalent of FeedConsumer from the Material app. I won’t bother covering these here.

The remaining thing to cover is our MainActivity:

This is pretty straightforward, we set out content view, finds instances of our DrawerLayout, and NavigationView objects, and set up the Toolbar, NavigationView and DataFragment. Let’s look at each of these in turn:

This finds the instance of our Toolbar from the layout sets it as the support ActionBar, and then set it up to show a hamburger menu icon.

This set up an item click listener which will get called whenever an item clicked. When this happens it will set the item as checked, close the drawer, and trigger a change in the selected article (more in this shortly).

This checks to see if there is already an instance of the DataFragment in the FragmentManager and creates a new instance (and stores is) if there isn’t.

Next we need to add a handler for the hamburger menu (which we have already set up) being pressed:

All that remains is to implement the ArticlesConsumer methods (as the activity implements this interface):

When the list of Articles is updated, setArticles() is called which constructs the new menu for our NavigationView and check the first one which will will display by default.

In the event of an error, handleError() gets called, and we construct a SnackBar to display the error. SnackBar is constructed in much the same way as a Toast with the addition of a View to which the SnackBar is associated. Normally this will be a child of a CoordinatorLayout (which we’ll cover later in the series) but for now we’ll just use our top level layout.

The remaining two methods set the current article – for now we’ll just change the title.

If we run this we see:

Part1-SnackBar

That’s when we remember to add the INTERNET permission to our manifest, but demonstrates that the SnackBar is working!

Adding the require permissions sees us with a fully working Navigation Drawer on API 21:

So, we have a working Navigation Drawer! In the next article we’ll Take a look at implementing the ViewPager for handling the individual article parts.

The source code for is available here.

© 2015, Mark Allison. All rights reserved.

CC BY-NC-SA 4.0 Design Library – Part 1 by Styling Android is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. Permissions beyond the scope of this license may be available at http://blog.stylingandroid.com/license-information.

3 Comments

  1. Hi Mark, in DataFragment you initialize VolleySingleton with inflater.getContext(), but inflater will return you Activity context, so after finishing MainActivity your VolleySingleton will contain reference to Activity context. And thanks for great article.

  2. Hy Mark,
    This is good and informative post. But i am getting error in activity_main.xml ‘headerlayout’ attribute is not found.

    Thanks
    Faisal Ahsan

Leave a Reply

Your email address will not be published. Required fields are marked *