ActionBarActivity#onOptionsItemSelectedのソースを追ってみた。
android.support.v7.app.ActionBarActivity
ActionBarActivityDelegate mImpl;
@Override
public final boolean onMenuItemSelected(int featureId, android.view.MenuItem item) {
if (mImpl.onMenuItemSelected(featureId, item)) {
return true;
}
final ActionBar ab = getSupportActionBar();
if (item.getItemId() == android.R.id.home && ab != null &&
(ab.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
return onSupportNavigateUp();
}
return false;
}
5行目で、ActionBarActivityDelegateのonMenuItemSelectedを呼び出している。ActionBarActivityDelegateを実装は幾つかのOSレベル毎に分かれているので、 その1つActionBarActivityDelegateBaseを見てみる。
android.support.v7.app.ActionBarActivityDelegateBase
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
item = MenuWrapperFactory.createMenuItemWrapper(item);
}
return mActivity.superOnMenuItemSelected(featureId, item);
}
ActionBarActivityのsuperOnMenuItemSelectedを呼んでいる。
android.support.v7.app.ActionBarActivity
boolean superOnMenuItemSelected(int featureId, MenuItem menuItem) {
return super.onMenuItemSelected(featureId, menuItem);
}
ActionBarActivityの親クラスFragmentActivityのonMenuItemSelectedを呼んでいる。
android.support.v4.app.FragmentActivity
/**
* Dispatch context and options menu to fragments.
*/
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
if (super.onMenuItemSelected(featureId, item)) {
return true;
}
switch (featureId) {
case Window.FEATURE_OPTIONS_PANEL:
return mFragments.dispatchOptionsItemSelected(item);
case Window.FEATURE_CONTEXT_MENU:
return mFragments.dispatchContextItemSelected(item);
default:
return false;
}
}
6行目の親クラスActivityActivityのonMenuItemSelectedを呼んでいる。メニューが処理されなかったら、Fragmentのメニューを呼び出している。
- Window.FEATURE_OPTIONS_PANEL - ActionBarや昔のメニューパネル
- Window.FEATURE_CONTEXT_MENU - ロングタップで表示されるコンテキストメニュー
android.app.Activity
public boolean onMenuItemSelected(int featureId, MenuItem item) {
CharSequence titleCondensed = item.getTitleCondensed();
switch (featureId) {
case Window.FEATURE_OPTIONS_PANEL:
// Put event logging here so it gets called even if subclass
// doesn't call through to superclass's implmeentation of each
// of these methods below
if(titleCondensed != null) {
EventLog.writeEvent(50000, 0, titleCondensed.toString());
}
if (onOptionsItemSelected(item)) {
return true;
}
if (mFragments.dispatchOptionsItemSelected(item)) {
return true;
}
if (item.getItemId() == android.R.id.home && mActionBar != null &&
(mActionBar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
if (mParent == null) {
return onNavigateUp();
} else {
return mParent.onNavigateUpFromChild(this);
}
}
return false;
case Window.FEATURE_CONTEXT_MENU:
if(titleCondensed != null) {
EventLog.writeEvent(50000, 1, titleCondensed.toString());
}
if (onContextItemSelected(item)) {
return true;
}
return mFragments.dispatchContextItemSelected(item);
default:
return false;
}
}
メニューは、12行目でonOptionsItemSelectedを呼び出し。
コンテキストメニューは、32行目でonContextItemSelectedを呼び出し。
リファレンスのOnMenuItemSelectedの記述
Default implementation of onMenuItemSelected(int, MenuItem) for activities. This calls through to the new onOptionsItemSelected(MenuItem) method for the FEATURE_OPTIONS_PANEL panel, so that subclasses of Activity don't need to deal with feature codes.
この通り、onOptionsItemSelectedをオーバーライドしてメニューの処理を実装を行なうのが正しいようだ。
コンテキストメニューはonContextItemSelectedをオーバーライドして処理を実装を行なうのが正しいようだ。
Honycombから、Activity#onMenuItemSelectedにはFragmentやActionBarのメニュー処理が行なわれてるためオーバーライドは注意が必要。
0 件のコメント:
コメントを投稿