12

我有一个可以包含多个片段的活动。每个片段都可以在 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 都应该调用它,这样我就不必在每个 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 放在每个片段中并在那里处理。有没有更好的方法来做到这一点?

4

4 回答 4

13

我刚刚遇到这个问题,我已经使用以下代码使其工作。在活动的onOptionsItemSelected函数中,添加:

if (id == android.R.id.home){
        Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.container);
        if(null != currentFragment && currentFragment.onOptionsItemSelected(item)){
            return true;
        }
    }

而在片段的onOptionsItemSelected方法中,你处理相应的事情。这样,如果fragment对菜单项有任何事情要做,它就会做它并返回true以停止任何其他进程。如果该片段与该项目没有任何关系,它将返回 false 或调用 super.onOptionsItemSelected 方法,该方法最终可能返回 false 让其他人处理它。

于 2015-05-01T12:43:28.430 回答
5

根据开发人员的参考,

“返回 false 以允许正常菜单处理继续进行,返回 true 以在此处使用它。”

因此,我会尝试在 Activity 的 onOptionsItemSelected() 实现中默认返回“false”,这样如果未捕获该事件,该事件将传递给 Fragment 的实现。

于 2013-07-20T22:41:00.117 回答
1

不确定是否可能。在此处提供的官方文档中:

http://developer.android.com/guide/topics/ui/actionbar.html#ActionEvents

有一个注释,说明如下:

[...] 但是,活动有机会首先处理事件,因此系统首先在活动上调用 onOptionsItemSelected(),然后再为片段调用相同的回调。

于 2015-04-08T14:03:12.690 回答
1

你可以像@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)
于 2018-10-03T15:10:10.547 回答