Save the date! Android Dev Summit is coming to Mountain View, CA on November 7-8, 2018.

Wear navigation and actions

This lesson describes how to implement action and navigation drawers in your app.

As part of Design for Wear OS by Google, two interactive drawers are available:

  • Navigation drawer. You can enable users to switch between views in your app.
    • Multi-page navigation drawer. You can present the contents of a navigation drawer in a single page or as multiple pages. To display the navigation drawer contents in multiple pages, use the app:navigationStyle attribute with a value set to multiPage.
  • Action Drawer. Lets you provide easy access to common actions in your app. The action drawer appears at the bottom of the screen and has context-specific user actions, similar to the action bar on a phone. The action drawer peeks when the user reaches the top or bottom of the scrolling content.

Figure 1. Navigation and Action Drawers.

For detailed information about the classes described on this page, see the API reference for the android.support.wear.widget.drawer package. The classes are in the Wear UI Library. For information about that library, and the deprecated classes (including classes formerly used for action and navigation drawers) that the Wear UI Library replaces, see Using the Wear UI Library.

Create a drawer layout

To add an action or a navigation drawer to your app, declare a user interface with a WearableDrawerLayout object as the root view of the layout. Inside the WearableDrawerLayout, if content is scrolling, it must support nested scrolling.

For example, the following layout uses a WearableDrawerLayout with three child views: A LinearLayout to contain the main content, a navigation drawer, and an action drawer.

<android.support.wear.widget.drawer.WearableDrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ScrollView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:nestedScrollingEnabled="true">
        <LinearLayout
            android:id="@+id/linear_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical" />
    </ScrollView>
    <android.support.wear.widget.drawer.WearableNavigationDrawerView
        android:id="@+id/top_navigation_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <android.support.wear.widget.drawer.WearableActionDrawerView
        android:id="@+id/bottom_action_drawer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:actionMenu="@menu/action_drawer_menu"/>
</android.support.wear.widget.drawer.WearableDrawerLayout>

Note: The WearableDrawerLayout class replaces a similar, deprecated class in the Wearable Support Library.

Create a multi-page navigation drawer

By default, a navigation drawer is a single-page drawer. However, a single page drawer may not be fitting for your app, especially if your app has more than seven views, or has views that are not easily represented with icons. To create a multi-page navigation drawer, apply the attribute navigationStyle="multiPage" to the drawer. For example:

<android.support.wear.widget.drawer.WearableNavigationDrawerView
    android:id="@+id/top_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_red_light"
    app:navigationStyle="multiPage"

Initialize the drawer contents

As one of the primary steps for an Activity, you initialize the drawers' lists of items. You must extend WearableNavigationDrawerAdapter to populate the navigation drawer contents. You can populate the action drawer contents in your layout XML file using the app:actionMenu attribute:

app:actionMenu="@menu/action_drawer_menu"
    

The following shows how to initialize the contents of your drawers:

public class MainActivity extends Activity implements
        OnMenuItemClickListener {
    private WearableDrawerLayout mWearableDrawerLayout;
    private WearableNavigationDrawerView mWearableNavigationDrawer;
    private WearableActionDrawerView mWearableActionDrawer;
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ...
        // Top navigation drawer
        mWearableNavigationDrawer = (WearableNavigationDrawerView) findViewById(R.id.top_navigation_drawer);
        mWearableNavigationDrawer.setAdapter(new YourImplementationNavigationAdapter(this));
        // Peeks navigation drawer on the top.
        mWearableNavigationDrawer.getController().peekDrawer();
        // Bottom action drawer
        mWearableActionDrawer = (WearableActionDrawerView) findViewById(R.id.bottom_action_drawer);
        // Peeks action drawer on the bottom.
        mWearableActionDrawer.getController().peekDrawer();
        mWearableActionDrawer.setOnMenuItemClickListener(this);
    }
}

Create a custom drawer view

To use custom views in drawers, add a WearableDrawerView to the WearableDrawerLayout. To set the peek view and drawer contents, add them as children of the WearableDrawerView and specify their IDs in the peekView and drawerContent attributes, respectively. Also specify the drawer position using either a top or bottom value for the android:layout_gravity attribute (only top and bottom are supported).

Custom peek views must specify their own top and bottom padding.

The following example specifies a top drawer with peek view and drawer contents:

<android.support.wear.widget.drawer.WearableDrawerView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="top"
    android:background="@color/red"
    app:drawerContent="@+id/drawer_content"
    app:peekView="@+id/peek_view">
    <FrameLayout
        android:id="@id/drawer_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <!-- Drawer content goes here.  -->
    </FrameLayout>
    <LinearLayout
        android:id="@id/peek_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:paddingTop="8dp"
        android:paddingBottom="8dp"
        android:orientation="horizontal">
        <!-- Peek view content goes here.  -->
    </LinearLayout>
</android.support.wear.widget.drawer.WearableDrawerView>

Listen for drawer events

To listen for drawer events, call setDrawerStateCallback() on your WearableDrawerLayout and pass it an implementation of WearableDrawerLayout.DrawerStateCallback. This abstract class provides callbacks for drawer events such as onDrawerOpened(), onDrawerClosed(), and onDrawerStatechanged().

Peeking drawers

To cause a drawer to peek, call getController() for access to peekDrawer(), closeDrawer(), and openDrawer().

For example:

mActionDrawer.getController().peekDrawer();

By default, the action drawer shows the first action with a chevron when there are multiple actions. If you prefer to display just the overflow icon (three vertical dots) without the first action, override the default behavior by setting the showOverflowInPeek flag to true. For example:

<android.support.wear.widget.drawer.WearableActionDrawerView
    android:id="@+id/bottom_drawer"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/holo_blue_dark"
    app:showOverflowInPeek="true"/>

By default, the action drawer peeks when a user reaches the top or bottom of the main scrolling content (that is, the view that implements NestedScrollingChild), whether from normal scrolling or from flings. If you prefer, you can make the drawer peek whenever the user is scrolling down, by setting the actionDrawer.setPeekOnScrollDownEnabled() method to true.

The navigation drawer, by default, peeks when a user arrives at the top of the content, either by normal scrolling or due to a fling.