AppCompat v7 工具栏 onOptionsItemSelected 未调用
Posted
技术标签:
【中文标题】AppCompat v7 工具栏 onOptionsItemSelected 未调用【英文标题】:AppCompat v7 Toolbar onOptionsItemSelected not called 【发布时间】:2014-12-22 17:04:45 【问题描述】:我从原来的ActionBar改成了AppCompat Toolbar和setSupportActionBar(toolbar)。 当我使用 getSupportActionBar() 和 setDisplayHomeAsUpEnabled(true) 作为后退箭头时,单击永远不会调用 onOptionsItemSelected 或任何其他侦听器方法。
我必须为它实现一些特殊的监听器吗?在一切正常之前。
编辑: 初始化 ActionBar:
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
mActionBar = getSupportActionBar();
mActionBar.setHomeButtonEnabled(true);
在用片段替换内容后,我这样做:
mDrawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);
mDrawerToggle.setDrawerIndicatorEnabled(false);
mActionBar.setDisplayHomeAsUpEnabled(true);
【问题讨论】:
你试过 setHasOptionsMenu(true) 吗? 我在活动中。当我按下后退箭头时,也不会调用 onSupportNavigateUp() 【参考方案1】:我知道这个问题已经得到解答,但经过 2 天的挫折后,我找到了问题的真正原因。
查看 ActionBarDrawerToggle 文档: https://developer.android.com/reference/android/support/v7/app/ActionBarDrawerToggle.html
注意那里的两个构造函数。我的错误是我使用了第二个将工具栏作为参数的构造函数。我花了很长时间才注意到构造函数文档中的最后一行: “如果您将 Toolbar 设置为 Activity 的 ActionBar,请使用 ActionBarDrawerToggle(Activity, DrawerLayout, int, int)。”
在使用第一个构造函数后,onOptionsItemSelected() 被调用,没有任何问题。
不要忘记从您的活动中调用 ActionBarDrawerToggle.onConfigurationChanged() 和 onOptionsItemSelected(),如上一部分所述:http://developer.android.com/training/implementing-navigation/nav-drawer.html
【讨论】:
哇。这些构造函数有点违反直觉。这绝对是我的问题。谢谢,你帮我省了几个小时敲墙的时间! 很好地找到了这个小块!我有完全相同的情况。 这应该是被接受的答案,因为接受的答案现在提供了一种解决方法,而不是解决实际问题的方法。 简而言之,如果我理解正确:将工具栏添加到 ActionBarDrawer 构造函数的参数时,导航箭头将在抽屉打开时显示,而汉堡包将在抽屉关闭时显示。不会调用主页按钮回调。在构造没有工具栏作为参数的 ActionBarDrawer 时,我们可以使用主页按钮回调。这意味着我们可以管理片段回栈。如何同步主页按钮以像在 Gmail 应用程序中一样对其进行动画处理?同样,在使用不带工具栏的选项作为参数汉堡包图标时,我并没有出现。任何解释将不胜感激。 谢谢你,也拯救了我的一天!那里有几十个问题和回答,但没有一个对我有用。我认为我们应该为这个问题添加一些关键字,例如 - “导航抽屉未显示汉堡包图标”或“导航抽屉未在菜单图标单击工具栏上打开”。【参考方案2】:我必须为 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);
);
这解决了我的问题。
【讨论】:
这不是正确的做法,除非你有充分的理由,否则不应处理切换点击。请参阅 Andrei 的解决方案。【参考方案3】:我在使用 setSupportActionBar() 方法时遇到了几个问题。它还会忽略某些颜色主题,因此您无法设置后退箭头或溢出图标的样式(不记得是哪个)。我只是取消了 ActionBar 的集成并在本地使用 Toolbar。因此,作为替代方案,您可以按以下方式执行此操作。
只需像往常一样在布局中包含工具栏,假设它使用@+id/toolbar 的ID。
然后,在代码中:
_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,这就是我猜的问题。 developer.android.com/reference/android/support/v7/widget/… @IgorGanapolsky,不,它在 android.support.v7.widget.Toolbar 中可用。【参考方案4】:没有提到的一件事: 如果您在 onCreateOptionsMenu 中动态构建选项菜单并在此处返回 null,则操作栏中的向上按钮将不起作用。 如果您返回 Menu 参数而不向其中添加任何内容,则可以正常工作。
在模拟器 API 19 上测试
【讨论】:
【参考方案5】:如果您已经尝试了所有方法,但仍然无法正常工作,您可以像这样实现自己的点击监听器:
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();
);
【讨论】:
【参考方案6】:在我的情况下,setHasOptionsMenu(true);
未在 onCreateView
上启用。希望这对某人有所帮助。
【讨论】:
以上是关于AppCompat v7 工具栏 onOptionsItemSelected 未调用的主要内容,如果未能解决你的问题,请参考以下文章
使用带有新工具栏的选项卡 (AppCompat v7-21)
带有 appcompat 库 v7 的 ActionBar(ava.lang.IllegalStateException:您需要使用 Theme.AppCompat 主题)
NoClassDefFoundError:解析失败:Landroid/support/v7/appcompat/R$styleable