156
148

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MaterialDesignことはじめ ActionBar編

Last updated at Posted at 2014-10-30

自分が関わるアプリにMaterialDesignを取り込んでいくために、試行錯誤したことをまとめます。(たぶん後で加筆すると思います。)

MaterialDesignにおけるActionBar

大きく分けると2種類あります。正確には本来のActionBarと、ActionBarの機能を持たせた新たなWidgetのToolBarの2つです。
左図がActionBarで右図がToolBarです。デフォルトでの影の付き方が異なるだけで、あとはほとんど一緒です。

actionbar_sample.png toolbar_sample.png

コードだと以下の通りです。(ここではAndroid4.4での実装を例にしてますので、appcompat-v7を使用してます。)

共通

dependencies {
    compile 'com.android.support:appcompat-v7:21.0.+'
}

ActinoBar

style.xml
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    </style>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    tools:context=".MainActivity">

    <TextView android:text="@string/hello_world" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</RelativeLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {

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

ToolBar

style.xml
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    </style>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <android.support.v7.widget.Toolbar
        android:id="@+id/sample_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"/>

    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/sample_toolbar"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="16dp"/>

</RelativeLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.sample_toolbar);
        setSupportActionBar(toolbar);
    }

ActionBarの実装で気をつけること

  1. いくらstyleやxmlでActionBarについて設定したとしても、最終的には作成するActivityクラスにActionBarActivityを継承させないと表示されませんでした。
  2. 影をつけたくないときは、getSupportActionBar().setElevation(0)すればいいっぽい。

ToolBarの実装で気をつけること

  1. styleで必ずNoActionBarのテーマを使う
  2. あくまでViewなのでレイアウトに気をつける
  3. 必ずonCreateでsetSupportActionBar()する

ナビゲーション・ドロワーを追加する

ActionBarでの実装の場合

ポイントは2点ありました。

  1. support.v7.app.ActionBarDrawerToggleクラスを使う
  • 3本線と矢印の画像やアニメーションなども自動でつく
  1. ナビゲーション部分のレイアウトをStart側に寄せる指定をする
  • 指定しないと実行は出来るけどクラッシュしました

ab_drawerlayout.png tb_drawerlayout.png

activity_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">

    <!-- content -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </RelativeLayout>

    <!-- nav drawer:ここをstart側に寄せる -->
    <LinearLayout
        android:layout_gravity="start"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:background="#fff">

        <ListView
            android:id="@+id/listview"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {

    private DrawerLayout vDrawerLayout;
    private ActionBarDrawerToggle vDrawerToggle;
    private ListView vListView;

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

        vDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        initDrawer();

        vListView = (ListView) findViewById(R.id.listview);
        vListView.setAdapter(new ArrayAdapter<String>(
                this, android.R.layout.simple_list_item_1, new String[]{"menu 1", "menu 2", "menu 3"}));
    }

    private void initDrawer() {
        // (3本線の)切り替えボタンの生成
        vDrawerToggle = new ActionBarDrawerToggle(this, vDrawerLayout, R.string.app_name, R.string.app_name);
        vDrawerToggle.setDrawerIndicatorEnabled(true);
        vDrawerLayout.setDrawerListener(vDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return vDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        vDrawerToggle.syncState();
    }

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

Toolbarでの実装の場合

やることはActionBarの時と同じですが、Toolbarをコンテンツ領域のwidgetとしてLayoutファイルに記述するため、Navigation部分が覆いかぶさってきます。

tb_dl.png tb_dl2.png

activity_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">

    <!-- content -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            android:background="?attr/colorPrimary" />

        <TextView
            android:text="@string/hello_world"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </LinearLayout>

    <!-- nav drawer -->
    <LinearLayout
        android:layout_gravity="start"
        android:layout_width="280dp"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="#fff">

        <ListView
            android:id="@+id/listview"
            android:layout_width="wrap_content"
            android:layout_height="match_parent" />

    </LinearLayout>

</android.support.v4.widget.DrawerLayout>
MainActivity.java
public class MainActivity extends ActionBarActivity {

    private DrawerLayout vDrawerLayout;
    private ActionBarDrawerToggle vDrawerToggle;
    private ListView vListView;

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

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        vDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        initDrawer();

        vListView = (ListView) findViewById(R.id.listview);
        vListView.setAdapter(new ArrayAdapter<String>(
                this, android.R.layout.simple_list_item_1, new String[]{"menu 1", "menu 2", "menu 3"}));
    }

    private void initDrawer() {
        vDrawerToggle = new ActionBarDrawerToggle(this, vDrawerLayout, R.string.app_name, R.string.app_name);
        vDrawerToggle.setDrawerIndicatorEnabled(true);
        vDrawerLayout.setDrawerListener(vDrawerToggle);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setDisplayShowHomeEnabled(true);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }

        return vDrawerToggle.onOptionsItemSelected(item) || super.onOptionsItemSelected(item);
    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        vDrawerToggle.syncState();
    }

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

どちらが良いか?

公式のガイドラインによると、Toolbarを使う形にしろと書いてあります。
けど、Google製アプリでもActionBarを使ってるものもあるし、今はまだケースバイケースかなーと感じます。

参考にしたサイト

156
148
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
156
148

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?