AppCompat v7工具栏的onOptionsItemSelected未被调用

43

我从原来的ActionBar改为了AppCompat工具栏,并使用setSupportActionBar(toolbar)进行设置。 当我使用getSupportActionBar()并将setDisplayHomeAsUpEnabled(true)用于返回箭头时,单击永远不会调用onOptionsItemSelected或任何其他侦听器方法。

我需要实现一些特殊的侦听器吗?之前一切都正常工作。

编辑: 初始化ActionBar:

mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mActionBar = getSupportActionBar();
mActionBar.setHomeButtonEnabled(true);

然后,用一个Fragment替换了内容之后,我做了这个:

mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
mActionBar.setDisplayHomeAsUpEnabled(true);

你尝试过使用 setHasOptionsMenu(true) 吗? - Nauman Afzaal
我正在活动中。当我按下返回箭头时,onSupportNavigateUp()也没有被调用。 - Informatic0re
6个回答

114

我知道这个问题已经有答案了,但是在两天的挣扎后,我找到了真正的问题所在。

看一下ActionBarDrawerToggle文档: https://developer.android.com/reference/android/support/v7/app/ActionBarDrawerToggle.html

注意那里的两个构造函数。我的错误在于我使用了第二个构造函数,它需要一个工具栏作为参数。花了我很长时间才注意到构造函数文档中的最后一行: "如果您正在将工具栏设置为活动的操作栏,请使用ActionBarDrawerToggle(Activity、DrawerLayout、int、int)。"

使用第一个构造函数后,onOptionsItemSelected()被调用而没有任何问题。

不要忘记从您的活动中调用ActionBarDrawerToggle.onConfigurationChanged()onOptionsItemSelected(),如此处的最后部分所述:http://developer.android.com/training/implementing-navigation/nav-drawer.html


2
简而言之,如果我理解正确: 当将工具栏添加到ActionBarDrawer构造函数的参数中时,当抽屉打开时,navuparrow将显示,当抽屉关闭时,hamburger将显示。主页按钮回调不会被调用。在没有工具栏作为参数构建ActionBarDrawer时,我们可以使用主页按钮回调。这意味着我们可以管理片段回退堆栈,例如。如何同步主页按钮以像Gmail应用程序中一样进行动画处理?同时,在使用没有工具栏作为参数的选项时,汉堡包图标对我来说根本不显示。任何解释都将不胜感激。 - Darek Deoniziak
2
谢谢,你救了我的一天!有很多问题和回答,但都不适用于我。我认为我们应该为这个问题添加一些关键词,比如“导航抽屉没有显示汉堡图标”或“在工具栏上单击菜单图标时导航抽屉没有打开”。 - mikron
在我的情况下,它没有帮助过我,甚至导航抽屉行为也发生了改变。因此,一个已接受的答案就帮到我了(在 http://stackoverflow.com/questions/34903326/toolbar-back-button-is-not-calling-onoptionsitemselected-android 中有)。但是我无法在 onCreateOptionsMenu 中创建菜单(尽管它被触发了)。 - CoolMind
如果有人使用了这个解决方案,但在使用他们的抽屉后遇到问题,您可以查看我的帖子这里 - Ben

28

我需要为DrawerToggle实现一个OnClickListener:

mDrawerToggle.setToolbarNavigationClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        popStackIfNeeded();
        mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED);
        mActionBar.setDisplayHomeAsUpEnabled(false);
        mDrawerToggle.setDrawerIndicatorEnabled(true);
    }
});

这解决了我的问题。


1
这不是正确的做法,除非你有充分的理由,否则不应该处理切换点击事件。请参考安德烈的解决方案。 - Genc

4

我在使用setSupportActionBar()方法时遇到了几个问题。它也忽略了某些颜色主题,因此您无法对返回箭头或溢出图标进行样式设置(不记得是哪个了)。我放弃了ActionBar的集成,改用原生的Toolbar。因此,作为替代方案,您可以按照以下步骤执行。

只需像通常一样在布局中包含工具栏,假设它使用id @+id/toolbar。

然后,在代码中:

_toolbar = (Toolbar) findViewById(R.id.toolbar);
_toolbar.setNavigationOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        handleNavButtonPress();
    }
});
_toolbar.setOnMenuItemClickListener(_menuItemClickListener);
_toolbar.inflateMenu(R.menu.message_list_menu);
Menu menu = _toolbar.getMenu();

在这种情况下,_menuItemClickListener几乎可以被视为您当前的onOptionsItemSelected()方法重命名。您不再需要检查菜单是否为空。
要从菜单中删除项目,只需调用menu->clear()。因此,在我的onPause中,我清除了菜单,在onResume中,我填充了它们,在我的片段中,每个片段都在onResume中设置了单击处理程序。您需要始终进行清理,因为Android不会在这种方法中为您执行清理操作,而工具栏将在每次填充时添加菜单。
最后一点,为使其正常工作,您必须完全禁用操作栏并将其从样式中删除。

在我的情况下,navigationOnClickListener从未被调用。但现在我想到了,我必须实现DrawerToggle setToolbarNavigationClickListener。顺便说一句,我正在使用NavigationDrawer,我想这就是问题所在。 - Informatic0re
https://developer.android.com/reference/android/support/v7/widget/Toolbar.html#setNavigationOnClickListener(android.view.View.OnClickListener) - reactive-core
1
@IgorGanapolsky,不是的,它可以在android.support.v7.widget.Toolbar中找到。 - CoolMind

0
如果你已经尝试了所有方法,但仍然无法解决问题,你可以像下面这样实现自己的点击监听器:
myNavList.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String item = myNavList.getItemAtPosition(position).toString();
        Toast.makeText(this, "You selected " + item, Toast.LENGTH_SHORT).show();
    }
});

0
有一件事没有提到:
如果您在 onCreateOptionsMenu 中动态构建选项菜单并返回 null,则操作栏中的向上按钮将无法正常工作。
如果您返回未添加任何内容的 Menu 参数,则可以正常工作。

在模拟器 API 19 上测试通过


0
在我的情况下,setHasOptionsMenu(true);onCreateView 上没有启用。希望这能帮助到某些人。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接