SherlockNavigationDrawerを使ってみた

2013-10-23T00:00:00+00:00 Android Java

んまぁSlidingMenuだったりだとか色々あるのですけど、Googleが公開したNavigationDrawer方式をベースに使えるようにした物がSherlockNavigationDrawerらしい、正しいかは微妙だけど。ちなみにデモアプリもあるのでちょっとどんな感じかってのを見たければそれ入れて確認してみるってのも可能

という事で使ってみた (ただ公式なサンプルを見て自分で書いてやってみただけなので、ほとんど同じ)

※AndroidManifest.xmlは特に特殊な事するわけでも無いので省略する

事前事項

もちろんの事ながらActionBarSherlockが必要になる訳だけど、確かGoogleが公開したNavigation Drawerなやつはandroid-support-v13に依存し、ActionBarSherlockはandroid-support-v4に依存しているっていうのがあったような気がするのだけど。それはおいといて、とにかくSherlockNavigationDrawerのreadmeにも

Update android-support-v4.jar to revision 13 or higher, in ActionBarSherlock libs folder or maven.

っていう風に明記されているのでまぁそれを事前に行なっておく必要あり。

あとはActionBarSherlockとSherlockNavigationDrawerなライブラリプロジェクトをインポートしておく。んでアプリプロジェクトでその2つのプロジェクトをライブラリとしてインポート出来るようにしておく

まぁ事前設定的なのはこんだけかと

res/layout/main_fragment.xml

<?xml version="1.0" ?>
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:scrollbarStyle="outsideOverlay">

        <!-- ここにコンテンツ部な所のUIを指定? -->
    </ScrollView>

    <ListView
        android:id="@+id/drawer"
        android:layout_width="200dp"
        android:layout_height="match_parent"
        android:layout_gravity="left"
        android:background="@android:color/white" />

</android.support.v4.widget.DrawerLayout>

MainActivity.java

package com.example.sample2;

import android.os.Bundle;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.ViewGroup.LayoutParams;
import android.widget.FrameLayout;

import com.actionbarsherlock.app.SherlockFragmentActivity;

public class MainActivity extends SherlockFragmentActivity {

    private static final int FRAME_VIEW_ID = 666;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FrameLayout layout = new FrameLayout(this);
        layout.setId(FRAME_VIEW_ID);

        setContentView(
            layout,
            new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        );

        if (savedInstanceState != null)
            return;

        FragmentManager fm = getSupportFragmentManager();
        FragmentTransaction tx = fm.beginTransaction();
        tx.add(FRAME_VIEW_ID, new MainFragment());
        tx.commit();
    }
}

ほんと公式的な方式で書いてるのでまったく同じなんですが、別に<fragment>でレイアウト書いて的な感じでも良いと思うのだけど

MainFragment.java

package com.example.sample2;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragment;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.sherlock.navigationdrawer.compat.SherlockActionBarDrawerToggle;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainFragment extends SherlockFragment {

    private static final String TAG = MainFragment.class.getName();

    private ActionBar mActionBar;
    private DrawerLayout mDrawerLayout;
    private SherlockActionBarDrawerToggle mDrawerToggle;
    private ListView mListView;

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        setRetainInstance(true);
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.activity_main, container, false);

        mActionBar = ((SherlockFragmentActivity)getActivity()).getSupportActionBar();
        mActionBar.setHomeButtonEnabled(true);

        mDrawerLayout = (DrawerLayout)view.findViewById(R.id.layout);
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
        mDrawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {

            @Override
            public void onDrawerOpened(View drawerView) {
                Log.v(TAG, "onDrawerOpened");
                mDrawerToggle.onDrawerOpened(drawerView);
            }

            @Override
            public void onDrawerClosed(View drawerView) {
                Log.v(TAG, "onDrawerClosed");
                mDrawerToggle.onDrawerClosed(drawerView);
            }

            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
                Log.v(TAG, "onDrawerSlide");
                mDrawerToggle.onDrawerSlide(drawerView, slideOffset);
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                Log.v(TAG, "onDrawerStateChanged");
                mDrawerToggle.onDrawerStateChanged(newState);
            }
        });

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(
            getActivity(),
            android.R.layout.simple_list_item_1
        );
        adapter.add("hoge");
        adapter.add("fuga");
        adapter.add("foobar");

        mListView = (ListView)view.findViewById(R.id.drawer);
        mListView.setAdapter(adapter);
        mListView.setOnItemClickListener(new ListView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
                if (!(view instanceof TextView))
                    return;

                Toast.makeText(
                    getActivity(),
                    "text: " + ((TextView)view).getText(),
                    Toast.LENGTH_LONG
                ).show();

                mDrawerLayout.closeDrawer(mListView);
            }
        });

        mDrawerToggle = new SherlockActionBarDrawerToggle(
            getActivity(),
            mDrawerLayout,
            R.drawable.ic_drawer_light,
            R.string.drawer_open,
            R.string.drawer_close
        );

        /*
        ActionBarにアイテムをおいてそれをタップする事でメニューを開いたりする必要性が
        なければfalseにする事で表示しないようにすることも出来る?
        */
        mDrawerToggle.setDrawerIndicatorEnabled(true);
        mDrawerToggle.syncState();

        return view;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item))
            return true;

        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mDrawerToggle.onConfigurationChanged(newConfig);
    }
}

まぁコンテンツ部に何を載せるとかそういう所以外は大体ざっくりとコード書いてるだけでやってる事はまーだいたい同じ。コメントにも書いてるが公式サンプルには無かったけど、ActionBar内にアイテムを設置しそれをタップすることでメニューを開いたりするのが必要ない場合には、SherlockActionBarDrawerToggle.setDrawerIndicatorEnabledをfalseにすることで表示もされないしアイコン部をタップしても反応はしなくなる

で実際動かしてみると

というような感じ。こういうUIを構築したいっていう場合の選択肢に入るかも

protractorを使ったangular.jsのe2eテスト angular.jsをやってみる (2) - $interpolateProvider -