2012年10月26日金曜日

Fragmentを使ってMenuを動的に作成する

Fragmentを使用して、アクションバー(Honeycombから追加されたツールバーの様な領域)にMenuを動的に作成します。

少し見にくいですが、図中の赤丸部分がアクションバーです。
右から
Activity#onCreateOptionsMenu  Menu#add し作成したMENU
・Fragment内で作成した MENU1A と MENU1B
となります。
表示スペースが足りない為、Fragmentで作成したMENU2は右端のMENU内に入っています。

※Activity#onCreateOptionsMenu で作成したMENU に関しては、オプションメニュー(OptionsMenu)を表示するを参照ください。

※プレビュー版SDKによる作成のため、正式版SDKではAPI仕様が変更になり、動作しない可能性があります。

それでは、続きで説明していきます。

PreferenceFragmentを使って2Paneな設定画面を作成する でも少しFragmentに触れましたが、
今回もFragmentのLifeCycleは使用しません。

初めに、Fragmentの登録を行います。
まず Activity#getFragmentManagerを用いて、FragmentManagerのインスタンスを取得します。
取得したインスタンスを用いて FragmentManager#beginTransaction からFragmentTransactionのインスタンスを取得します。

FragmentTransactionクラスで行う主な事は以下の通りです。

FragmentTransaction
add(Fragment fm,String tag) フラグメントの追加

※addだけでは追加されない

commit() 変更点を全て反映する。

※変更後は commit を忘れない様に!

show(Fragment fm) 引数のFragmentを表示状態とする。
hide(Fragment fm) 引数のFragmentを非表示状態とする。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//FragmentManagerを取得
FragmentManager fm = getFragmentManager();
 
//Fragmentの管理
// add() -> commit() で追加
// show() で表示
// hide() で非表示
FragmentTransaction ft = fm.beginTransaction();
mFragment1 = fm.findFragmentByTag("f1"); //既に作成済みであるか検索
if (mFragment1 == null) {
    mFragment1 = new MenuFragment(); //後述のクラス
    ft.add(mFragment1, "f1");
}
mFragment2 = fm.findFragmentByTag("f2"); //既に作成済みであるか検索
if (mFragment2 == null) {
    mFragment2 = new Menu2Fragment(); //後述のクラス
    ft.add(mFragment2, "f2");
}
ft.commit();

次に、Fragmentを継承したクラスを作成します。
Fragment#onCreateOptionsMenu をOverrideし、Menu#addを用いてMENUを追加します。
これらはActivityの場合と何ら変わりありません。
もちろん、Fragment#onOptionsItemSelected をOverriceすることで、MENUがSelectされた時の動作を記載することも可能です。

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
public static class MenuFragment extends Fragment {
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
    }
 
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        /*
         * add( int groupId,
         *  int itemId,
         *  int order,
         *  int titleRes //title string or resource identifier )
         */
        menu.add(Menu.NONE, FRAGMENT_MENU1, Menu.NONE, "FragmentMenu 1a").setShowAsAction(
                MenuItem.SHOW_AS_ACTION_IF_ROOM);
        menu.add(Menu.NONE, FRAGMENT_MENU2, Menu.NONE, "FragmentMenu 1b").setShowAsAction(
                MenuItem.SHOW_AS_ACTION_IF_ROOM);
    }
 
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean ret = true;
 
        switch (item.getItemId()){
        case 1:
            Log.v(LOGTAG,"menu 1a is pushed");
            break;
        case 2 :
            Log.v(LOGTAG,"menu 1b is pushed");
            break;
        default:
            ret = super.onOptionsItemSelected(item);
            break;
        }
        return ret;
    }
}

続いて、動的にボタンの表示/非表示を設定する部分を記述します。
今回は、CheckBoxに対して、ONなら表示OFFなら非表示としています。
上述のFragmentTransactionクラス show と hide を使用しています。
本処理は以下場所に付加しています。
・onClick-Method
・onRestoreInstanceState()
・onCreate() 終端

1
2
3
4
5
6
7
8
9
10
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (mCheckBox1.isChecked())
    ft.show(mFragment1);
else
    ft.hide(mFragment1);
if (mCheckBox2.isChecked())
    ft.show(mFragment2);
else
    ft.hide(mFragment2);
ft.commit();

これで、Fragmentを使用したアクションバーへのMENUボタンの表示が行えました。
ポイントは、
・基本的な使用方法は、Activity内でMENUを表示させるときと同様の方法で設定できる。
・動的にON/OFFを切り替える事ができる。
・Activityで作成する、既存のMENUは、存在すれば右上にMENUBOTTONが、
無ければ、何も表示されない。
ところかと思います。

0 件のコメント:

コメントを投稿