ActionBarにパンくずリストを表示する


Webページなどで、表示中のページの階層構造を表示する為にパンくずリスト(BreadCrumbs)を利用することがあります。
Androidでも、FragmentBreadCrumbsクラスを利用することで、パンくずリストを利用し、画面の階層などを解りやすく表示することができます。

本エントリでは、FragmentBreadCrumbsを利用して、ActionBarパンくずリストを表示する方法を紹介していきます。
FragmentBreadCrumbsはその名の通り、Fragmentと強く結びついているため、特定ActivityへのFragmentの追加を読み取り、自動でパンくずリストを表示してくれます。

それではつづきをどうぞ。

サンプルアプリケーションの構成

まず始めに、パンくずリストを紹介するためのサンプルアプリケーションを紹介します。


■初期画面

本エントリでは、上図の「アプリケーション起動時の画面」を初期状態と呼んでいます。
初期状態では、Defaultのパンくずが表示されていますが、新たにActivityにFragmentが追加されるまでdisable状態となっています。
この状態で、「AddA」や「AddB」のボタンを押下すると、以下の画面に遷移します。


■オブジェクト追加時

上図のように、各ボタンを押下した回数だけ、正方形のFragmentとパンくずが追加されていきます。
複数のFragmentを追加した後に、ActionBarのパンくずを押下すると、その時の状態を復元します。
Defaultの右隣の「A」を押下した時には以下画面に遷移します。


■パンくず選択時(A選択)

追加されていた各Fragmentが無くなり、初期状態にAを追加した状態が復元されます。

それでは、このアプリケーションの動作に習って、FragmentBreadCrumbsの使い方を紹介していきます。

ActionBarにFragmentBreadCrumbsを追加する

FragmentBreadCrumbsをカスタムViewとしてActionBarにセットすることで、ActionBar内にFragmentBreadCrumbsを表示することができます。
ActionBarへのカスタムViewのセットにはActionBarクラスのsetCustomViewメソッドを利用します。
カスタムViewを利用するためには、setDisplayShowCustomEnabledメソッドを利用して、カスタムViewの表示設定をtureにしておく必要がありますので気をつけましょう。

ActionBarへFragmentBreadCrumbsをセットするサンプルコードは以下の通りになります。

	private FragmentBreadCrumbs mFragmentBreadCrumbs;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// 省略...

		// ActionBarの取得
		final ActionBar mActionBar = getActionBar();

		// ActionbarにFragmentBreadCrumbsをセット
		mFragmentBreadCrumbs = new FragmentBreadCrumbs(this);
		mActionBar.setCustomView(mFragmentBreadCrumbs);
		mActionBar.setDisplayShowCustomEnabled(true);

		// パンくず表示の為ActionBarのタイトルを非表示に
		mActionBar.setDisplayShowTitleEnabled(false);

12行目でFragmentBreadCrumbsをActionBarに追加、13行目でカスタムViewの表示設定をtrueに設定しています。
また、16行目ではActionBarにパンくずリストを表示するため、ActionBarの標準状態で表示しているタイトルの表示をfalseに変更しています。

パンくずの内容を設定する

FragmentBreadCrumbsを使用するためには、「FragmentBreadCrumbsをActivityにセット」を行う必要があります。
FragmentBreadCrumbsをActivityへセットする為には、setActivityメソッドを利用します。この操作を忘れた場合、Null Pointer Exceptionが発生してしまいますので注意しましょう。

また、setParentTitleメソッドを使って初期状態を示すパンくず(スクリーンショットでのDefaultボタン)を表示することができます。
setParentTitleメソッドにはView.OnClickListenerを渡すことができます。
OnClickListenerには、初期状態のパンくずをタッチした時の処理を記述できます。

パンくずの内容を設定する部分に該当するサンプルコードは以下の通りになります。
本エントリでは、初期状態を示すパンくずをタッチした時には、初期状態に戻すための処理を記述しています。

		// FragmentBreadCrumbsをActivityにAttachする
		// (無いとNull Pointer Exceptionになる)
		mFragmentBreadCrumbs.setActivity(this);

		// 初期状態を示すBreadCrumbを作成する
		mFragmentBreadCrumbs.setParentTitle("Default", null,
				new OnClickListener() {
					@Override
					public void onClick(View v) {
						Toast.makeText(self, "Click ParentTitle",
								Toast.LENGTH_SHORT).show();

						// 初期状態に戻す
						FragmentManager fm = getFragmentManager();
						for (int i = 0; i < fm.getBackStackEntryCount(); i++) {
							fm.popBackStack();
						}
					}
				});

3行目でFragmentBreadCrumbsをActivityにセットしています。
setActivityメソッドの引き数には、セットするActivityを引き渡します。
6行目では初期状態のパンくずを作成しています。
setParentTitleメソッドには、表示するパンくずのタイトルを引き渡します。
第三引き数には、タッチした時に呼び出すメソッドを記述しています。
onClickメソッド内で、初期状態へ戻す処理を行っています。
FragmentManagerクラスのgetBackStackEntryCountメソッドを利用すると、バックスタックに入っているFragmentの数を取得することができるので、その数だけpopBackStackメソッドを呼び出し状態を復元しています。
Fragmentをバックスタックに追加する処理については、次項で説明しています。

Fragmentを追加する時にパンくずを追加する

FragmentBreadCrumbsを利用してパンくずを表示するときは、Fragmentの追加や削除をAndroidOSが管理してくれるため、Fragmentに対して複雑な処理を追加する必要はありません。
FragmentTransactionへFragmentを追加する際にパンくずに表示するタイトルを設定するのみです。
タイトルの設定にはFragmentTransactionクラスのsetBreadCrumbTitleメソッドを利用します。

サンプルアプリケーションでは、各ボタンの押下時にFragmentを追加しています。
ボタン押下時の処理とFragmentの実装は以下の通りです。

	@Override
	public void onClick(View v) {
		SampleFragment fragment = null;
		switch (v.getId()) {
		case R.id.button1:
			// Add Fragment A
			fragment = new SampleFragment(Color.BLUE, "A");

			break;
		case R.id.button2:
			// Add Fragment B
			fragment = new SampleFragment(Color.YELLOW, "B");

			break;
		case R.id.button3:
			// Add Fragment C
			fragment = new SampleFragment(Color.GREEN, "C");

			break;
		default:
			break;
		}
		if (fragment != null) {
			// 選択したFragmentを追加する
			FragmentTransaction ft = getFragmentManager().beginTransaction();
			ft.add(R.id.fragment_root, fragment);
			ft.addToBackStack(null);

			// BreadCrumbの名前を追加
			ft.setBreadCrumbTitle(fragment.getName());
			ft.commit();
		}
	}

	private class SampleFragment extends Fragment {
		int colorCode;
		String name;

		/**
		 * コンストラクタ FragmentA B C の特徴を入力する
		 *
		 * @param color
		 *            Yellow or Blue or Green
		 * @param n
		 *            AorBorC
		 */
		SampleFragment(int color, String n) {
			colorCode = color;
			name = n;
		}

		public String getName() {
			return name;
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View v = inflater.inflate(R.layout.fragment_layout, container,
					false);
			((TextView) v.findViewById(R.id.textView1))
					.setBackgroundColor(colorCode);
			((TextView) v.findViewById(R.id.textView1)).setText(name);
			return v;
		}

	}

27行目でFragmentをバックスタックに追加しています。
30行目でパンくずリストへ追加するタイトルを設定しています。
タイトルは35行目以降で作成しているSampleFragmentクラスのgetNameメソッドから取得するようにしています。
SampleFragmentクラスはコンストラクタに引き渡すカラーコードと文字列を変更することで、A,B,Cと使い分けています。
Fragmentの利用方法の詳細は、Fragmentを動的に変化させるを参考にどうぞ。