Android4.0(以降ICS)ではメニューを再描画させるためのメソッド”invalidateOptionsMenu”がFragmentManagerクラスに追加されました。
このinvalidateOptionsMenuメソッドはActivityクラスではAndroid3.0(API level11)から追加されていますが、Fragmentからメニューの再描画を促したい場合はFragmentManager#invalidateOptionsMenuを使用することが必須となっています。
このinvalidateOptionsMenuメソッドを使用することで動的にメニューのレイアウトを変更することが可能になります。
invalidateOptionsMenuメソッドの詳細は以下から。
invalidateOptionsMenuを使用したメニューのレイアウトの変更方法
invalidateOptionsMenuメソッドが呼び出されるとActivityクラスのonCreateOptionsMenuメソッドが呼ばれます。
メニューのレイアウトを変更したい場合はメニューのレイアウトのバリエーションをメニューのレイアウトファイルに定義しておいて、メニューのレイアウトを管理する変数を用意し、onCreateOptionsMenuメソッドではレイアウト管理用の変数ごとに読み込むメニューのレイアウトファイルを変更する実装がシンプルでコードの可読性も上がります。
下記のサンプルはmMenuTypeというメニューのレイアウト管理用変数を用意して、その中身の状態によって読み込むメニューのレイアウトファイルを切り替えています。
InvalidateOptionsMenuSampleActivity.java
/**
* メニューレイアウト管理用変数
*/
public static int mMenuType = 1;
/**
* メニューのレイアウトファイルmenu_aを表す
*/
public static final int MENU_TYPE_A = 1;
/**
* メニューのレイアウトファイルmenu_bを表す
*/
public static final int MENU_TYPE_B = 2;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.change_menu_button);
btn.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// メニューレイアウト管理用変数が切り替わる度にメニューのレイアウトを切り替える
switch (mMenuType) {
case MENU_TYPE_A:
getMenuInflater().inflate(R.menu.menu_a, menu);
break;
case MENU_TYPE_B:
getMenuInflater().inflate(R.menu.menu_b, menu);
break;
default:
break;
}
return super.onCreateOptionsMenu(menu);
}
メニューのレイアウトを切り替える仕組みができたところで、実際にFragmentからメニューを更新してみましょう。
まず、InvalidateOptionsMenuSampleActivity.javaにFragmentをコミットするための処理を追加します。
下記のコードでは画面内のボタンが押下される度にFragmentがコミットされます。
InvalidateOptionsMenuSampleActivity.java
public void onClick(View v) {
// フラグメントをコミットする
InvalidateOptionsMenuFragment fragment = new InvalidateOptionsMenuFragment();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.add(R.id.sample_fragment, fragment);
ft.commit();
}
次にInvalidateOptionsMenuFragmentのコードを下記に記述します。
このFragmentはonResumeが呼ばれる度に親Activityのメニューレイアウト管理用変数を変更し、メニューの再描画を行います。
InvalidateOptionsMenuFragment.java
public class InvalidateOptionsMenuFragment extends Fragment{
public InvalidateOptionsMenuFragment() {
}
@Override
public void onResume() {
super.onResume();
// 親Activityのメニュー管理用変数を切り替える
switch (InvalidateOptionsMenuSampleActivity.mMenuType) {
case InvalidateOptionsMenuSampleActivity.MENU_TYPE_A:
InvalidateOptionsMenuSampleActivity.mMenuType = InvalidateOptionsMenuSampleActivity.MENU_TYPE_B;
break;
case InvalidateOptionsMenuSampleActivity.MENU_TYPE_B:
InvalidateOptionsMenuSampleActivity.mMenuType = InvalidateOptionsMenuSampleActivity.MENU_TYPE_A;
break;
default:
break;
}
getFragmentManager().invalidateOptionsMenu();
}
}
21行目でFragmentManager#invalidateOptionsMenuメソッドを使用して、親Activityのメニューを再描画しています。


