読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

最近流行のNavigationDrawer

Android

今回のエンジニアブログを担当させて頂きます、佐藤です。

最近のアプリで画面端をスワイプすると横からメニュー画面が開くUIが多く使われています。
今回はその機能について調べてみました!

この機能はNavigation Drawer(ナビゲーション ドロワー)という名前がついています。
Androidのサポートライブラリに含まれています。
この機能を使用する際、デザインガイドラインで様々な原則があるので注意してください。

◆ Navigation Drawerの特徴
Navigation Drawerの特徴は、アクションバーの左端にアプリアイコンと三本線のマークです。
こちらの三本線マークもNavigation Drawerを使用時に追加するよう推奨されています。
この三本線マークは、Android Developersの「Creating a Navigation Drawer」ページからダウンロードできるので、そのままresフォルダへ上書きしてください。

◆ Navigation Drawerのレイアウト
Navigation Drawerのレイアウトはxmlで作成していきます。
レイアウトをandroid.support.v4.widget.DrawerLayoutで囲み、その中にメインのコンテンツとドロワーのViewを入れていきます。
このとき、ドロワーの方はwidthは320dp以内であったり,gravityをstart(またはleft)にしなければならないという制約があるので注意してください。

今回の完成はこんな感じです。

Screenshot_2014-05-23-05-06-03

xmlとjavaコードはこのようになっています

main.xml

<android.support.v4.widget.DrawerLayout  
  xmlns:android="http://schemas.android.com/apk/res/android"  
  android:id="@+id/drawer_layout"  
  android:layout_width="match_parent"  
  android:layout_height="match_parent" >  
  
  <!-- The main content view -->  
  
  <LinearLayout  
    android:id="@+id/left_draw"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <TextView  
      android:id="@+id/drawer_main_text"  
      android:layout_width="match_parent"  
      android:layout_height="100dp"  
      android:gravity ="center" />  
   
  </LinearLayout>  
  
  <!-- NavigatonDrawer部分 -->  
  
  <LinearLayout  
    android:id="@+id/left_drawer"  
    android:layout_width="240dp"  
    android:layout_height="match_parent"  
    android:layout_gravity="left"  
    android:background="#FFF" >  
  
    <TextView  
      android:id="@+id/drawer_text"  
      android:layout_width="match_parent"  
      android:layout_height="48dp"  
      android:gravity = "center" />  
  
  </LinearLayout>  
</android.support.v4.widget.DrawerLayout>  

MainActivity.java

import android.content.res.Configuration;  
import android.os.Bundle;  
import android.support.v4.app.ActionBarDrawerToggle;  
import android.support.v4.widget.DrawerLayout;  
import android.support.v7.app.ActionBarActivity;  
import android.view.MenuItem;  
import android.view.View;  
import android.widget.TextView;  
  
public class MainActivity extends ActionBarActivity {  
  
    // ActionBarの代わりに使用します。  
    private ActionBarDrawerToggle mDrawerToggle;  
  
    // NavigationDrawerのレイアウト  
    private DrawerLayout mDrawer;  
  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
  
        setContentView(R.layout.main);  
  
        // メインコンテンツ部分のView  
        TextView mainText = (TextView)findViewById(R.id.drawer_main_text);  
        mainText.setText("メインコンテンツ部分");  
  
        // NavigationDrawerに表示するView  
        TextView navigateText = (TextView)findViewById(R.id.drawer_text);  
        navigateText.setText("メニューです");  
  
        mDrawer = (DrawerLayout) findViewById(R.id.drawer_layout);  
  
        /**  
         * ActionBarDrawerToggleクラスを作成  
         * Activity,NavagationDrawerのレイアウト,三本線のアイコン,開閉時のアクション説明文をそれぞれ指定  
         */  
        mDrawerToggle = new ActionBarDrawerToggle(  
                this,  
                mDrawer,  
                R.drawable.ic_drawer,  
                R.string.drawer_open,  
                R.string.drawer_close) {  
            @Override  
            public void onDrawerClosed(View drawerView) {  
                //NavigationDrawerが閉じきった  
            }  
  
            @Override  
            public void onDrawerOpened(View drawerView) {  
                // Navigation Drawerが開ききった  
            }  
  
            @Override  
            public void onDrawerSlide(View drawerView, float slideOffset) {  
                // アイコンのアニメーションの処理  
                super.onDrawerSlide(drawerView, slideOffset);  
            }  
  
            @Override  
            public void onDrawerStateChanged(int newState) {  
                // NavigationDrawerの状態が変更された時  
            }  
        };  
  
        // 作成したActionBarDrawerToggleを設置  
        mDrawer.setDrawerListener(mDrawerToggle);  
  
        getActionBar().setDisplayHomeAsUpEnabled(true);  
        getActionBar().setHomeButtonEnabled(true);  
  
    }  
  
    @Override  
    protected void onPostCreate(Bundle savedInstanceState) {  
        super.onPostCreate(savedInstanceState);  
        // Activityの開始が完了したとき、ActionBarDrawerToggleの状態を同期させる  
        mDrawerToggle.syncState();  
    }  
  
    @Override  
    public void onConfigurationChanged(Configuration newConfig) {  
        super.onConfigurationChanged(newConfig);  
        // Activityが変更した時に、ActionBarDrawerToggleも変更させる  
        mDrawerToggle.onConfigurationChanged(newConfig);  
    }  
  
    @Override  
    public boolean onOptionsItemSelected(MenuItem item) {  
  
        if (mDrawerToggle.onOptionsItemSelected(item)) {  
            // ボタンが押された時、ActionBarDrawerToggleにNavigationDrawerの開閉させる  
            return true;  
        }  
  
        return super.onOptionsItemSelected(item);  
    }  
}  

ActionBarではなくActionBarDrawerToggleを使用します。
ActionBarDrawerToggleでオープン、クローズ、スワイプ中などドロワーの状態を取得します。

また、ActionBarDrawerToggleの作成をする時コンストラクタでActivity,NavagationDrawerのレイアウト,三本線のアイコン,開閉時のアクション説明文をそれぞれ指定しています。
元々 < マークのついているアイコンを表示し、三本線のアイコンを指定することで上書きを表示する仕組みになっています。

表示するViewをわかりやすくする為に、今回はTextViewを表示しましたが勿論ListViewも表示することができます。

複雑そうに思っていたNavigation Drawerもサポートライブラリを使用すれば、基本的なところは案外そこまで難しくはないと思いました!