我有一个可以包含多个片段的活动。每个片段都可以在ActionBar中拥有自己的菜单条目。到目前为止,此工作正常,每个项目都是可点击的,并执行所需的操作。
我的问题如下。在MainActivity中,我声明了以下几行来拦截对ActionBar的HomeIcon的调用:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
clearBackStack();
setHomeFragment();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
我在Activity中声明了它,因为我希望每个Fragment都应该调用它,以便我不必捕获每个片段中的android.R.id.home情况。
在一个片段中我使用setDisplayHomeAsUpEnabled(true),这样我就可以得到ActionBar图标左侧的小箭头。当在这个片段中单击HomeIcon时,我不想设置HomeFragment,我想设置上次显示的片段。所以我有一个onOptionsItemSelected - 片段中的方法:
@Override
public boolean onOptionsItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case android.R.id.home:
setLastFragment();
return true;
...
然而,这并不像我希望的那样工作。首先调用Activity的onOptionsItemSelected,捕获MenuItem并重定向到HomeFragment。使用在其他片段中声明的其他MenuItems,我可以检查看到相同的行为。首先调用Activity,不捕获MenuItem(默认情况),然后重定向到super.onOptionsItemSelected(item)。
所以看来这就是Android处理菜单点击的方式。第一个活动,然后是片段。有没有办法改变这个?我不想把android.R.id.home-case放在每个片段中并在那里处理它。有更好的方法吗?
答案 0 :(得分:13)
我刚刚遇到这个问题,我使用以下代码使其工作。
在活动的onOptionsItemSelected
功能中,添加:
if (id == android.R.id.home){
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
if(null != currentFragment && currentFragment.onOptionsItemSelected(item)){
return true;
}
}
在片段的onOptionsItemSelected
方法中,您可以处理相应的事情。
这样,如果片段对菜单项有任何操作,它将执行此操作并返回true以停止任何其他进程。
如果片段与此项没有任何关系,它将返回false或调用super.onOptionsItemSelected方法,该方法最终可能返回false以让其他人处理它。
答案 1 :(得分:4)
根据开发人员的参考,
“返回false以允许正常的菜单处理继续进行,在此处使用它是真的。”
所以我会在Activity的onOptionsItemSelected()实现中默认返回'false',这样事件就会在没有捕获的情况下传递给Fragment的实现。
答案 2 :(得分:1)
不确定是否可行。在这里提供的官方文档中:
http://developer.android.com/guide/topics/ui/actionbar.html#ActionEvents
有一条说明,说明如下:
[...]但是,活动有机会首先处理事件,因此系统首先在活动上调用onOptionsItemSelected(),然后再调用片段的相同回调。
答案 3 :(得分:0)
您可以按照@Surely编写的方法进行操作,这是个好主意,但是在这种情况下,您将对片段调用onOptionsItemSelected
而不知道它是哪个片段,并且您应该在所有片段中重写onOptionsItemSelected
如果您只想为特定片段调用此方法,则应按添加它们时所使用的标签找到它们:
case android.R.id.home:
Fragment frag = getSupportFragmentManager()
.findFragmentByTag(FRAGMENT_TAG);
if(frag != null && frag.isVisible() && frag.onOptionsItemSelected(item)) {
return true;
标签的指定方式如下:
fragmentManager.beginTransaction()
.add(containerId, fragment, FRAGMENT_TAG)