【发布时间】:2014-02-21 15:28:11
【问题描述】:
我可以从我的NavigationDrawerFragment 中成功拦截ActionBar 主页按钮,该按钮添加到我的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;
}
}
如下面的 sn-p 所示,Activity 在检查它或它的任何片段是否可以处理事件之后,将处理主页按钮作为最后的手段。但是这个对FragmentManager 的引用不包含任何片段,这些片段在FragmentActivity 的管理器中。因此,如果设置了ActionBar.DISPLAY_HOME_AS_UP,该事件将被Activity 类吞噬。
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中,我可以手动将事件传递给我的每个片段,看看它们是否可以在调用 super 之前处理它。 - 覆盖
ComposeActivity中的 onMenuItemSelected 并执行相同的操作。
有人遇到过这种情况吗?我应该在某处记录错误吗?解决此问题的任何其他想法?
【问题讨论】:
-
问题解决了吗?我正在尝试处理片段的
onOptionsItemSelected()中的android.R.id.home,但它永远不会到达片段。 -
我目前在基本活动中接收
android.R.id.home操作,并在调用超级方法之前将其传递给所有片段。一种解决方法。 -
这里一样,我想我希望有更好的解决方案
-
不理想。但是,嘿,现在我们很高兴更新我们的应用程序以支持 Lollipop!
标签: android android-fragments android-actionbar android-fragmentactivity android-appcompat