Я могу успешно перехватить кнопку 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 и бросил библиотеку поддержки.
Что касается обходных путей для этого, я думаю, я мог:
- В моем
ComposeActivity
onOptionsItemSelected
я могу вручную передать событие каждому из моих фрагментов, видя, могут ли они обработать его до вызова супер. - Переопределить onMenuItemВыбран в
ComposeActivity
и сделать то же самое.
Кто-нибудь сталкивался с этим раньше? Должен ли я где-нибудь регистрировать ошибку? Любые другие идеи путей решения этой проблемы?