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をセットするサンプルコードは以下の通りになります。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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には、初期状態のパンくずをタッチした時の処理を記述できます。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 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の実装は以下の通りです。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
@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を動的に変化させるを参考にどうぞ。