NavigationViewを使ってGoogle Play風のメニューを作る【Android Design Support Library】

More than 1 year has passed since last update.

概要

最近GoogleからDesign Support Libraryが公開されましたね。

こいつを使うことで、Googleのアプリで使われているマテリアルデザイン用のUIが簡単に利用できます。

まだ情報も少ないので、今回はNavigationViewの使い方を少し詳しくまとめてみました。

ソースコードはGithubにあげてあるので、よかったら参考にしてください。(他のViewも実装してます)
https://github.com/chuross/DesignSupportLibrarySample

NavigationViewとは?

Google Play等のGoogle製アプリで使われているナビゲーションドロワーを実装できるViewです。

これを使う事で、今まで自分でRelativeLayoutをListViewにaddHeaderViewするような悲しい実装をこいつ一つでできるようになりました。

こんな感じ
device-2015-06-03-042350.png

特徴

  • メニューのXMLを書くと、そこからViewを自動生成してくれる
  • ヘッダーレイアウトXMLとメニューXMLの指定をレイアウトXML上で表現できる
    • 自分でfindViewByIdした後にヘッダーレイアウトXMLやメニューXMLを指定するコードを書く必要がない
  • クリックイベントの処理もActivityに配置するメニュー感覚で処理できる

作り方

前置きは以上で、ここから実際にDesign Support Libraryの導入からGoogle Play風のドロワーを作るところまで紹介します。

導入

Android Support Repositoryの更新

Android SDK Managerを起動し、Android Support Repositoryを更新します。

snapshot.png

Extrasの中にあるよ!

build.gradleに追加

自分のプロジェクトのdependenciesにDesign Support Libraryを追加します

compile 'com.android.support:design:22.2.0'

例)

dependencies {
    // android standard lib
    compile 'com.android.support:design:22.2.0'
    compile 'com.android.support:appcompat-v7:22.2.0'
    ...
}

実装

DrawerLayoutの中にNavigationViewを記述する

app:headerLayoutにはヘッダーのレイアウトのリソースIDを指定します。
app:menuには表示する項目のメニューのリソースIDを指定します。

<android.support.v4.widget.DrawerLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

    <!-- your content layout -->

    <android.support.design.widget.NavigationView
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="start"
            app:headerLayout="@layout/drawer_header"
            app:menu="@menu/drawer"/>
</android.support.v4.widget.DrawerLayout>

ヘッダーのXMLを作成する

基本的にはヘッダーに表示したいレイアウトXMLをいつも通りに書いていけば問題ないです。

例)

drawer_header.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:background="@color/primary_dark_material_light" />

メニューのXMLを作成する

Androidのmenu xmlのルールに沿って記述していきます。

groupはメニュー項目の集合を表します。
<item> -> <menu> -> <item>の入れ子を使うとサブヘッダーを表示できます。

drawer.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group
        android:checkableBehavior="single">
        <item
            android:id="@+id/menu_home"
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="ホーム" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="視聴履歴" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="ブックマーク" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="マイページ" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="検索" />
    </group>
    <item
        android:title="その他">
        <menu android:checkableBehavior="single">
            <item
                android:title="お知らせ" />
            <item
                android:title="このアプリについて" />
            <item
                android:title="設定" />
        </menu>
    </item>
</menu>

実行

実行するとこんな感じのドロワーメニューが表示されれば完成です。
あとは好みでガシガシカスタマイズしていきましょう。

device-2015-06-03-042035.png

おまけ

待って!Google Playの方はサブヘッダー無いよ!
サブヘッダー表示したくない時にはどうすればいいの?と思った人もいるかと思います。

今回の例の場合のように、サブヘッダーが表示している文字列に意味はないので消したい、
しかし上のメニューと線で区切りたいというケースはあると思います。

最初の方に貼ったデベロッパーブログには特に言及されてなかったのでコード読んで調べてみました。

NavigationViewの中にNavigationMenuPresenterというクラスがあり、どうやらそいつが内部メニュー項目の生成を行っているようです。

実装方法は単純で、groupにidを振ると別物のグループとして認識してセパレートを自動的に配置してくれるようです。便利ですね。

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group
        android:id="@+id/menu_main"
        android:checkableBehavior="single">
        <item
            android:id="@+id/menu_home"
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="ホーム" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="視聴履歴" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="ブックマーク" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="マイページ" />
        <item
            android:icon="@android:drawable/ic_menu_gallery"
            android:title="検索" />
    </group>
    <group
        android:id="@+id/menu_other"
        android:checkableBehavior="single">
        <item
            android:title="お知らせ" />
        <item
            android:title="このアプリについて" />
        <item
            android:title="設定" />
    </group>
</menu>

サブヘッダーが無くなった!

device-2015-06-03-041454.png