2012/01/06

MENUキー押下でonPrepareOptionsMenuが呼ばれない問題


Honeycomb以降、ActivityのonCreate時にonCreateOptionsMenuとonPrepareOptionsMenu
が呼ばれるようになりました。
# アクションアイテム実装による変更かな?

注意するべきは、Activity起動後のMENUキー押下1回目にonPrepareOptionsMenuが
呼ばれなくなったということです。
# 2回目以降のMENUキー押下時はonPrepareOptionsMenuが呼ばれます。
もしonPrepareOptionsMenuでメニュー項目を動的に変更する、あるいは有効/無効を切
り変えるようなアプリは要注意です。

例えば、チェックボックスのON/OFFでメニュー項目の状態を変化させるために、
onPrepareOptionsMenuでチェックボックスの状態をチェックしてメニュー項目の状態を
動的に変更するような場合です。
1回目のMENUキー押下時はonPrepareOptionsMenuが実行されないため、正しくチェ
ックボックスの状態に合わせてメニュー項目を更新することができません。

解決方法の一つに、1回目のMENUキー押下時にも強制的にonPrepareOptionsMenu
を実行させて、従来通りのシーケンスを再現する方法があります。

1回目のMENUキー押下時にonPrepareOptionsMenuが実行されない原因は、Activity
のonCreate時にメニューが準備(onPrepareOptionsMenu)されることで、1回目のMENU
キー押下時の準備処理は不要と判断されるためです。

そこで、ActivityのonKeyDown処理で1回目のMENUキー押下時にオプションメニュー
を一度破棄します。
オプションメニューを破棄するにはinvalidateOptionsMenuを使用します。
オプションメニューを破棄することで、再度オプションメニューを表示しようとする時、
onCreateOptionsMenu⇒onPrepareOptionsMenuと呼ばれるようになります。

private boolean oneTimeFlag = true;
public boolean onKeyDown(int keyCode, KeyEvent event) {
  if (oneTimeFlag && keyCode == KeyEvent.KEYCODE_MENU) {
    invalidateOptionsMenu();
    oneTimeFlag = false;
  }
}

参考:Android Developer

以上です。