In this codelab, you'll learn how to improve your Wear 2.0 stand-alone applications with navigation and action components.

What you'll learn

What you'll need

How would you rate your experience with building Android apps?

Novice Intermediate Proficient

If you have Git installed, you can simply run the command below. (You can check if Git is installed by typing git --version in the terminal / command line and verify it executes correctly.)

$ git clone https://github.com/googlecodelabs/navigation-action.git

If you do not have Git, you can download the project as a zip file:

Download Zip

First, run the basic messaging app, which simply creates a notification.

  1. Open Android Studio
  2. Select the navigation-action directory from the code folder (File > New > mport Project... > navigation-action).
  3. Select the "base" module.
  4. Enable USB debugging and plug in your Android device or start your emulator
  5. Click the Android Studio Run button (or press shift+F10).
  6. After a few seconds, the app will appear with a screen like the one below:

Right now not all the sections are accessible to the user in the SectionFragment. Let's add them using a navigation drawer.

  1. Open the layout file activity_main.xml
  2. Change the outer container from android.support.wearable.view.BoxInsetLayout to android.support.wearable.view.drawer.WearableDrawerLayout.
  3. Search for "TODO:NAV Add WearableNavigationDrawer." and add a android.support.wearable.view.drawer.WearableNavigationDrawer tag below the existing NestedScrollView, and give it the id "top_navigation_drawer", and set both its width and height to match_parent.

Your code should look like this:

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.drawer.WearableDrawerLayout 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/container"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context="com.example.android.wearable.navaction.MainActivity"
   tools:deviceIds="wear">

   <android.support.v4.widget.NestedScrollView
       android:id="@+id/content"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:fillViewport="true">

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

   </android.support.v4.widget.NestedScrollView>

   <android.support.wearable.view.drawer.WearableNavigationDrawer
       android:id="@+id/top_navigation_drawer"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

   <!-- TODO:ACTIONS Add WearableActionDrawer -->

</android.support.wearable.view.drawer.WearableDrawerLayout>
  1. Go back to MainActivity.java
  2. At the bottom of MainActivity, search for "TODO:NAV Add NavigationAdapter here." and add the following inner class to act as an adapter for the navigation drawer:
// TODO:NAV Add NavigationAdapter here.
private final class NavigationAdapter
       extends WearableNavigationDrawer.WearableNavigationDrawerAdapter {

   private final Context mContext;
   private Section mCurrentSection = DEFAULT_SECTION;

   NavigationAdapter(final Context context) {
       mContext = context;
   }

   @Override
   public String getItemText(int index) {
       return mContext.getString(SectionFragment.Section.values()[index].titleRes);
   }

   @Override
   public Drawable getItemDrawable(int index) {
       return mContext.getDrawable(SectionFragment.Section.values()[index].drawableRes);
   }

   @Override
   public void onItemSelected(int index) {
       SectionFragment.Section selectedSection = SectionFragment.Section.values()[index];

       // Only replace the fragment if the section is changing.
       if (selectedSection == mCurrentSection) {
           return;
       }
       mCurrentSection = selectedSection;

       final SectionFragment sectionFragment = SectionFragment.getSection(selectedSection);
       getFragmentManager()
               .beginTransaction()
               .replace(R.id.fragment_container, sectionFragment)
               .commit();
   }

   @Override
   public int getCount() {
       return SectionFragment.Section.values().length;
   }
}
  1. Search for "TODO:NAV Uncomment the following block to add a navigation drawer." in the onCreate method, and uncomment the block of code it references. After you're done it should now look like this:

    MainActivity.java
// TODO:NAV Uncomment the following block to add a navigation drawer.
mWearableNavigationDrawer =
       (WearableNavigationDrawer) findViewById(R.id.top_navigation_drawer);
mWearableNavigationDrawer.setAdapter(new NavigationAdapter(this));

Now that the app has been updated, click theRun button (or press shift+F10).

Single Page

As you've seen, a user has to scroll through a set of options to get to their desired choice, but it's possible to make a change and present all of the options on a single screen.

  1. Open the layout file activity_main.xml again
  2. Add the attribute app:navigation_style="single_page" to the WearableNavigationDrawer tag you had just created. It should look like this now:

activity_main.xml

<android.support.wearable.view.drawer.WearableNavigationDrawer
   android:id="@+id/top_navigation_drawer"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:navigation_style="single_page"/>

That's it! Run the app again and you'll see all the navigation targets at a glance.

Navigation is only one part of interacting with an app, however. In the next step we'll add support for actions.

Where the navigation drawer fills the role of the side menu of a phone, the action drawer fills the role of the floating action button, and is built the same way!

  1. Right click in the "res" folder and select File -> New -> Android Resource File

  1. Fill in the options as follows:
    File name: action_drawer_menu
    Resource type: Menu
    Leave the remaining options as they're set:
  2. Paste the following as the contents of the new file, replacing what was there:
    action_drawer_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
   <item
       android:id="@+id/action_edit"
       android:icon="@drawable/ic_edit_black_24dp"
       android:title="@string/action_edit"/>
   <item
       android:id="@+id/action_share"
       android:icon="@drawable/ic_share_black_24dp"
       android:title="@string/action_share"/>
</menu>
  1. Open activity_main.xml again.
  2. Search for "TODO:ACTIONS Add WearableActionDrawer." and add the following code:
<android.support.wearable.view.drawer.WearableActionDrawer
   android:id="@+id/bottom_action_drawer"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   app:action_menu="@menu/action_drawer_menu"/>
  1. Open MainActivity.java
  2. Search for "TODO:ACTIONS Add code for WearableActionDrawer here." and add the following code:
// TODO:ACTIONS Add code for WearableActionDrawer here.
mWearableActionDrawer = (WearableActionDrawer) findViewById(R.id.bottom_action_drawer);
mWearableActionDrawer.setOnMenuItemClickListener(
       new WearableActionDrawer.OnMenuItemClickListener() {
           @Override
           public boolean onMenuItemClick(MenuItem menuItem) {
               mWearableActionDrawer.closeDrawer();
               switch (menuItem.getItemId()) {
                   case R.id.action_edit:
                       Toast.makeText(
                               MainActivity.this,
                               R.string.action_edit_todo,
                               Toast.LENGTH_SHORT)
                               .show();
                       return true;
                   case R.id.action_share:
                       Toast.makeText(
                               MainActivity.this,
                               R.string.action_share_todo,
                               Toast.LENGTH_SHORT)
                               .show();
                       return true;
               }
               return false;
           }
       });

With actions added, it's time to check the app. ClickRun (or press shift+F10) again.

You may have noticed that the action drawer is available on every screen, including settings. In the next step we'll make a change to address this.

The same actions don't always apply to all of the screens in an app. In this app, it doesn't make sense to "edit" or "share" from the settings screen. The easiest way to prevent this is to lock the WearableActionDrawer closed while the user is modifying the settings.

  1. Open MainActivity, and locate the method onItemSelected in our NavigationAdapter. Replace the current method with this code:

MainActivity.java

@Override
public void onItemSelected(int i) {
   SectionFragment.Section selectedSection = SectionFragment.Section.values()[i];
   final SectionFragment sectionFragment = SectionFragment.getSection(selectedSection);
   getFragmentManager()
           .beginTransaction()
           .replace(R.id.fragment_container, sectionFragment)
           .commit();

   // Lock the drawer closed on settings, and unlock it elsewhere
   if (selectedSection == SectionFragment.Section.Settings) {
       mWearableActionDrawer.lockDrawerClosed();
   } else {
       mWearableActionDrawer.unlockDrawer();
   }
}

Try it out. You'll see that it's now not possible to open the action drawer while on the setting screen.

You've updated the app to provide access to all of the sections, added in an action drawer, and configured it to respond contextually. Great job!

What we've covered

Next Steps

If you are interested in learning more about standalone apps for Wear OS, take a look at our guides. If watch faces sound interesting, check out the codelab "Create a watchface for Wear OS" or perhaps "Adding Complications to your Wear OS Watch Face".

Also, take a look at our drawer sample, which is a more complete example of how to use navigation and action drawers in your Wear OS app.

Learn More