Я могу успешно перехватить кнопку ActionBar home из моего NavigationDrawerFragment, который добавлен в мой MainActivity, например:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (!loggedIn() && item.getItemId() == android.R.id.home) {
login();
return true;
}
return super.onOptionsItemSelected(item);
}
Однако в моем ComposeActivity с ComposeFragment это не работает. onOptionsItemSelected не вызывается для фрагмента.
Я отлаживал код, и проблема, похоже, сводится к дизайну библиотеки поддержки Android. Похоже, что как FragmentActivity, так и Activity имеют свои собственные ссылки на FragmentManager.
FragmentActivity сначала проверяет, может ли Activity обработать событие перед проверкой любого из его фрагментов, что согласуется с docs:
/**
* 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;
}
}
Как показано в приведенном ниже фрагменте, Activity обрабатывает домашнюю кнопку в качестве последнего средства, после проверки того, сможет ли она или любой из ее фрагментов обработать событие. Но эта ссылка на FragmentManager не содержит фрагментов, фрагменты находятся в менеджере FragmentActivity. Поэтому событие будет проглочено классом Activity, если установлено ActionBar.DISPLAY_HOME_AS_UP.
public boolean onMenuItemSelected(int featureId, MenuItem item) {
/* ... */
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;
/* ... */
}
Оказывается, мой MainActivity, являющийся корнем моего приложения и использующий ящик для навигации, не установил этот флаг и не проглотил событие. Но мой ComposeActivity имеет родительскую активность, и мне нужно, чтобы этот флаг был установлен, поэтому невозможно перехватить домашнюю кнопку панели действий.
Подводя итог проблеме: Невозможно перехватить клик на Кнопка "Действие" на домашней кнопке из фрагмента в действии с помощью DISPLAY_HOME_AS_UP.
Значит, это ошибка в библиотеке поддержки? Не похоже, что это произойдет, если я нацелен на более позднюю версию Android и бросил библиотеку поддержки.
Что касается обходных путей для этого, я думаю, я мог:
- В моем
ComposeActivityonOptionsItemSelectedя могу вручную передать событие каждому из моих фрагментов, видя, могут ли они обработать его до вызова супер. - Переопределить onMenuItemВыбран в
ComposeActivityи сделать то же самое.
Кто-нибудь сталкивался с этим раньше? Должен ли я где-нибудь регистрировать ошибку? Любые другие идеи путей решения этой проблемы?