2013年6月11日火曜日

[Android] Navigation Drawerを画面上側から表示させる

Support Package revision 13でNavigation Drawerを作るためのクラス(DrawerLayoutとかActionBarDrawerToggleとか)が追加されました。

しかし、Navigation Drawerは左側固定で変更することができません。
それを右側から表示するように変更する!...にしようと思いましたが、ActionBarDrawerToggleのGravity.LEFTをGravity.RIGHTに変更したらできてしまったので、今回は上側から表示させるようにしました。

※Navigation Drawerのデザインガイドに準拠してないので使用する場合は自己責任でお願いします。

作成したのは以下のクラスです。それぞれDrawerLayout、ActionBarDrawerToggleの左右の処理を上下の処理に変更しました。

  • VerticalDrawerLayout.java
  • ActionBarVerticalDrawerToggle.java

使用例

MainActivity.java
public class MainActivity extends Activity {
    private VerticalDrawerLayout mDrawerLayout;
    private ListView mDrawerList;
    private ActionBarVerticalDrawerToggle mDrawerToggle;

    private CharSequence mDrawerTitle;
    private CharSequence mTitle;
    private String[] mPlanetTitles;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTitle = mDrawerTitle = getTitle();
        mPlanetTitles = getResources().getStringArray(R.array.planets_array);
        mDrawerLayout = (VerticalDrawerLayout) findViewById(R.id.drawer_layout);
        mDrawerList = (ListView) findViewById(R.id.top_drawer);

        // set a custom shadow that overlays the main content when the drawer opens
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, Gravity.TOP);
        // set up the drawer's list view with items and click listener
        mDrawerList.setAdapter(new ArrayAdapter<string>(this,
                R.layout.drawer_list_item, mPlanetTitles));
        mDrawerList.setOnItemClickListener(new DrawerItemClickListener());

        // enable ActionBar app icon to behave as action to toggle nav drawer
        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the sliding drawer and the action bar app icon
        mDrawerToggle = new ActionBarVerticalDrawerToggle(
                this,                  /* host Activity */
                mDrawerLayout,         /* DrawerLayout object */
                R.drawable.ic_drawer,  /* nav drawer image to replace 'Up' caret */
                R.string.drawer_open,  /* "open drawer" description for accessibility */
                R.string.drawer_close  /* "close drawer" description for accessibility */
                ) {
            public void onDrawerClosed(View view) {
                getActionBar().setTitle(mTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }

            public void onDrawerOpened(View drawerView) {
                getActionBar().setTitle(mDrawerTitle);
                invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
            }
        };
        mDrawerLayout.setDrawerListener(mDrawerToggle);

        if (savedInstanceState == null) {
            selectItem(0);
        }
    }

    ...

}
Navigation Drawerのサンプルを使用しました。DrawerLayoutをVerticalDrawerLayoutに、ActionBarDrawerToggleをActionBarVerticalDrawerToggleに置き換えました。

activity_main.xml
<android.support.v4.widget.VerticalDrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

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

    <ListView
        android:id="@+id/top_drawer"
        android:layout_width="match_parent"
        android:layout_height="240dp"
        android:layout_gravity="top"
        android:choiceMode="singleChoice"
        android:divider="@android:color/transparent"
        android:dividerHeight="0dp"
        android:background="#111"/>
</android.support.v4.widget.VerticalDrawerLayout>
DrawerLayoutをVerticalDrawerLayoutに、android:layout_gravityを"top"に変更します。

実行


上からスワイプまたは左上の画像をタップで、Navigation Drawerが上側から表示されました∩( ´∀` )∩
android:layout_gravityを"bottom"、ActionBarVerticalDrawerToggle#setGravity()にGravity.BOTTOMを設定することで下側からも表示できます。


まとめ
Navigation Drawerの上下表示はまだしも、右側表示はできるようにしないと右手だけで操作する人(私です)は左からスワイプするという操作が難しいので不便。。。

ソース
https://github.com/lilylight/VerticalNavigationDrawer