Wear のナビゲーションとアクション

このレッスンでは、アプリにアクション ドロワーとナビゲーション ドロワーを実装する方法について説明します。

Wear OS by Google のデザインの一部として、次の 2 つのインタラクティブなドロワーを使用できます。

  • ナビゲーション ドロワー: ユーザーがアプリのビューを切り替えられるようにすることができます。
    • 複数ページのナビゲーション ドロワー: ナビゲーション ドロワーのコンテンツは、単一ページ内に表示することも、複数ページとして表示することも可能です。ナビゲーション ドロワーのコンテンツを複数のページに表示するには、値が multiPage に設定された app:navigationStyle 属性を使用します。
  • アクション ドロワー: アクション ドロワーでは、アプリ内の共通のアクションに容易にアクセスできます。アクション ドロワーは画面の一番下に表示され、コンテキスト固有のユーザー アクションを実行できます(スマートフォンのアクションバーに似ています)。アクション ドロワーは、ユーザーがコンテンツをスクロールして一番上または一番下に達したときにせり出します。
    • タイトルの設定: アクション ドロワーのタイトルは、( WearableActionDrawerView の) setTitle() メソッドまたは app:drawerTitle 属性を使用して設定できます。

図 1. ナビゲーション ドロワーとアクション ドロワー

このページで説明するクラスについて詳しくは、 androidx.wear.widget.drawer パッケージの API リファレンスをご覧ください。これらのクラスは Wear UI ライブラリに含まれています。Wear UI ライブラリの詳細と、このライブラリが後を継いだサポート終了済みのクラス(以前にアクション ドロワーとナビゲーション ドロワー用に使用されていたクラスを含む)については、Wear UI ライブラリを使用するをご覧ください。

ドロワー レイアウトを作成する

アクション ドロワーまたはナビゲーション ドロワーをアプリに追加するには、 WearableDrawerLayout オブジェクトをレイアウトのルートビューに指定してユーザー インターフェースを宣言します。WearableDrawerLayout 内でコンテンツがスクロールする場合は、ネストされたスクロールをサポートする必要があります。

たとえば、次のレイアウトでは、3 つの子ビューを持つ WearableDrawerLayout が使用されています。LinearLayout には、メイン コンテンツ、ナビゲーション ドロワー、アクション ドロワーが含まれます。

    <androidx.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"/>
    </androidx.wear.widget.drawer.WearableDrawerLayout>
    

注: WearableDrawerLayout は、ウェアラブル サポート ライブラリのサポートが終了した類似クラスの後継クラスです。

複数ページのナビゲーション ドロワーを作成する

デフォルトでは、ナビゲーション ドロワーは単一ページのドロワーです。ただし、単一ページのドロワーは、特にアプリに 8 個以上のビューがある場合や、アイコンで表すことが容易でないビューがある場合は、アプリに適さないことがあります。複数ページのナビゲーション ドロワーを作成するには、属性 navigationStyle="multiPage" をドロワーに適用します。次に例を示します。

    <androidx.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">
    

ドロワーのコンテンツを初期化する

アクティビティの主な手順の 1 つとして、ドロワーのアイテムリストの初期化があります。ナビゲーション ドロワーのコンテンツを設定するには、WearableNavigationDrawerAdapter を拡張する必要があります。app:actionMenu 属性を使用すると、レイアウトの XML ファイルでアクション ドロワーのコンテンツを設定できます。

    app:actionMenu="@menu/action_drawer_menu"
        

以下に、ドロワーのコンテンツを初期化する方法を示します。

Kotlin

    class MainActivity : Activity(), MenuItem.OnMenuItemClickListener {

        private lateinit var wearableDrawerLayout: WearableDrawerLayout
        private lateinit var wearableNavigationDrawer: WearableNavigationDrawerView
        private lateinit var wearableActionDrawer: WearableActionDrawerView
        ...
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            ...
            // Top navigation drawer
            wearableNavigationDrawer = findViewById(R.id.top_navigation_drawer)
            wearableNavigationDrawer.setAdapter(YourImplementationNavigationAdapter(this))
            // Peeks navigation drawer on the top.
            wearableNavigationDrawer.controller.peekDrawer()
            // Bottom action drawer
            wearableActionDrawer =
                    findViewById<WearableActionDrawerView>(R.id.bottom_action_drawer).apply {
                        // Peeks action drawer on the bottom.
                        controller.peekDrawer()
                        setOnMenuItemClickListener(this@MainActivity)
                    }
        }
    }
    

Java

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

カスタムのドロワービューを作成する

ドロワーでカスタムビューを使用するには、 WearableDrawerView WearableDrawerLayout に追加します。ピークビューとドロワー コンテンツを設定するには、それらを WearableDrawerView の子として追加し、peekView 属性と drawerContent 属性でそれぞれ ID を指定します。また、android:layout_gravity 属性の値として top または bottom を使用して(topbottom のみがサポートされています)、ドロワーの位置を指定します。

カスタムのピークビューでは、上部と下部の独自のパディングを指定する必要があります。

次の例では、ピークビューとドロワー コンテンツが設定された上部ドロワーを指定しています。

    <androidx.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>
    </androidx.wear.widget.drawer.WearableDrawerView>
    

ドロワー イベントをリッスンする

ドロワー イベントをリッスンするには、 WearableDrawerLayoutsetDrawerStateCallback() を呼び出して、WearableDrawerLayout.DrawerStateCallback の実装を渡します。この抽象クラスは、ドロワー イベントのコールバック(onDrawerOpened()onDrawerClosed()onDrawerStatechanged()など)を提供します。

ドロワーのピーク動作

ドロワーがせり出す(ピーク)ようにするには、getController() を呼び出して、peekDrawer()closeDrawer()openDrawer() にアクセスできるようにします。

次に例を示します。

Kotlin

    wearableActionDrawer.controller.peekDrawer()
    

Java

    wearableActionDrawer.getController().peekDrawer();
    

複数のアクションがある場合、アクション ドロワーにはデフォルトで、最初のアクションが山形の矢印とともに表示されます。最初のアクションを表示せずにオーバーフロー アイコン(その他アイコン)のみを表示する場合は、showOverflowInPeek フラグを true に設定してデフォルトの動作をオーバーライドします。次に例を示します。

    <androidx.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"/>
    

アクション ドロワーはデフォルトでは、ユーザーがメイン コンテンツ(つまり、NestedScrollingChild を実装しているビュー)をスクロール(通常のスクロールまたはフリング)して一番上または一番下に達したときにせり出します。必要に応じて、actionDrawer.setPeekOnScrollDownEnabled() メソッドを true に設定することで、ユーザーが下にスクロールしたときに必ずドロワーがせり出すようにすることができます。

ナビゲーション ドロワーはデフォルトでは、ユーザーが通常のスクロールまたはフリングを行って、コンテンツの一番上に達したときに表示されます。