この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Support Library に ActionBar のサポートが追加
7月24日に Android SDK 4.3 (APIレベル18) がリリースされ、ADT r18 がリリースされ、Support Library r18 がリリースされました。Support Library r18 では v7 で ActionBar が正式にサポートされました!
ということで新しく追加された ActionBarActivity を早速使ってみたのでメモしておきます。
Support Package v7 をインポートする
ActionBarActivity を使う上でまず必要なのが Support Package v7 です。このライブラリは Android 2.1 (APIレベル7) から使うことができます。Android Studio のプロジェクトであれば、build.gradle の dependencies に Support Package v7 のリポジトリを追加します。
build.gradle
dependencies {
compile 'com.android.support:support-v4:13.0.+'
compile 'com.android.support:appcompat-v7:18.0.+'
}
これで ActionBar, ActionBarActivity (ついでに ShareActionProvider) が使えるようになりました。
ActionBarActivity を使う
それでは ActionBarActivity を使ってみましょう。まずはテーマに Theme.AppCompat か Theme.AppCompat.Light か Theme.AppCompat.Light.DarkActionBar を設定します。その他のテーマはこちらを参照してください。
<style name="AppBaseTheme" parent="Theme.AppCompat.Light">
</style>
あとは Activity の親を ActionBarActivity に差し替えます。
public class MainActivity extends ActionBarActivity {
…
}
これで終わりです。めっちゃ簡単ですね! 2.3.3 で実行してみました。
ActionBarActivity の ActionBar をいろいろカスタマイズする
せっかくなので色々試してみたいと思います。
タブを置いてみる
まずはタブを置いてみました。ActionBar の取得は getSupportActionBar() ですね。
ActionBar ab = getSupportActionBar();
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
ab.addTab(ab.newTab().setText("Tab1").setTabListener(mTabListener));
ab.addTab(ab.newTab().setText("Tab2").setTabListener(mTabListener));
ab.addTab(ab.newTab().setText("Tab3").setTabListener(mTabListener));
実行結果
ドロップダウンリストを表示する
次にドロップダウンリスト形式のナビゲーションにしてみました。
ActionBar ab = getSupportActionBar();
ab.setDisplayShowTitleEnabled(false);
ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
SpinnerAdapter adapter = ArrayAdapter.createFromResource(
this, R.array.list, android.R.layout.simple_list_item_1);
ab.setListNavigationCallbacks(adapter, new ActionBar.OnNavigationListener() {
@Override
public boolean onNavigationItemSelected(int i, long l) {
return false;
}
});
実行結果
ちなみに Spinner が ICS のやつになってる!と思って見てみたら SpinnerICS というクラスを内部的に使っているみたいでした。このクラスは Internal なのでレイアウトでは使えませんでした。。
NavigationDrawer を使う
最近追加されたばかりの新しいナビゲーションパターンである NavigationDrawer を用いたナビゲーションも実装できます。まずは以下のようなレイアウトにします。
<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">
<!-- コンテンツ -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- Navigation Drawer -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:background="#eee" />
</android.support.v4.widget.DrawerLayout>
次に Activity の実装です。公式のサンプルと同じように実装しましょう。
package jp.classmethod.android.sample.actionbar;
import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
public class MainActivity extends ActionBarActivity {
private DrawerLayout mDrawerLayout;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar ab = getSupportActionBar();
ab.setDisplayHomeAsUpEnabled(true);
ab.setHomeButtonEnabled(true);
// DrawerLayout
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// DrawerListを開く/閉じるトグルボタン
mDrawerToggle = new ActionBarDrawerToggle(
this,
mDrawerLayout,
R.drawable.ic_drawer,
R.string.open,
R.string.close
);
mDrawerLayout.setDrawerListener(mDrawerToggle);
// DrawerList
mDrawerList = (ListView) findViewById(R.id.left_drawer);
ArrayAdapter adapter = ArrayAdapter.createFromResource(
this, R.array.list, android.R.layout.simple_list_item_1);
mDrawerList.setAdapter(adapter);
mDrawerList.setOnItemClickListener(mOnItemClickListener);
}
private AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
// DrawerLayoutを閉じる
mDrawerLayout.closeDrawer(mDrawerList);
}
};
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// DrawerToggleの状態を同期する
mDrawerToggle.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// DrawerToggleの状態を同期する
mDrawerToggle.onConfigurationChanged(newConfig);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
ちなみにリソースに使っているアイコンも公式のサンプルからダウンロードできます。
これで実行すると以下のようになります!ActionBarSherlock だとそのままではアイコンが表示されなかったりしましたが、アニメーションも含めて正しく表示されました。
ActionBarSherlock から移行したい場合
ActionBarSherlock から移行する方法は以下にまとめられています。
ActionBarSherlock の API は標準 SDK の API に沿って実装されているので、テーマの定義と Activity と Fragment の親クラスの変更さえできればスムーズに移行可能できるようです。
まとめ
ActionBar が公式でサポートされたことにより、2系でも差し支えなく ActionBar を用いた実装ができるようになりました。今回は ActionBar の UI の実装を主に取り扱いましたがリファレンスを眺めてみると Up ナビゲーションのサポートも充実しているようでした(supportNavigateUpTo() やら onPrepareSupportNavigateUpTaskStack() やら)。
今後もバージョンアップしていくと思われるので、期待しましょう!
またデザインガイドラインをよく読んで、ユーザーが迷わないよう一貫したナビゲーションを提供するようにしましょう。