如何在 ContextMenu 中使用 MenuItem.setIntent()
Posted
技术标签:
【中文标题】如何在 ContextMenu 中使用 MenuItem.setIntent()【英文标题】:How to use MenuItem.setIntent() in a ContextMenu 【发布时间】:2019-08-14 15:26:07 【问题描述】:我有一个上下文菜单,其中包含一个应该启动意图的菜单项:
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo)
MenuItem item = menu.add(menuItemText);
item.setIntent(intent);
这曾经可以工作,但在较新的 android 版本中,它会引发异常:
从 Activity 上下文之外调用 startActivity() 需要 FLAG_ACTIVITY_NEW_TASK 标志。这真的是你想要的吗?
添加此标志将是一种简单的方法,但我不想创建新任务,因为它应该是应用程序活动堆栈的一部分。问题是系统调用startActivity
哪个项目的上下文,在这种情况下是DecorContext
,而不是Activity
。由于这一切都由框架处理,因此我无法控制。
除了设置标志或处理onContextItemSelected
中的操作之外,还有什么好的解决方案吗?
【问题讨论】:
安卓版本较新是什么意思?你能指定版本吗? @MithunSarkerShuvro 我在可以追溯到 2010 年的问题中看到对错误消息的引用,所以我认为错误消息本身一直存在,但 Android 已经改变了这里传递的上下文。它曾经是 Activity,现在它是一个单独的上下文,DecorContext
。
【参考方案1】:
这是因为从 Android 27 开始,Android 使用 DecorContext
进行活动。
You can see the change here.
您可以通过查看line 319 in PhoneWindow 的内部来在系统级别确认这一点。请注意,当 PhoneWindow
从 Activity 构造时,mUseDecorContext
始终设置为 true。这意味着您的菜单每次都会使用 DecorContext 构建。
我的理解是,为ContextMenu
设置一个单独的DecorContext
是故意的。 ContextMenus
旨在“浮动”在内容之上,因此可以作为与显示它们的内容不同的菜单。
根据您使用ContextMenu
的目的,您可能不得不考虑等到onContextItemSelected
之前构建Intent
,即使您提到您希望避免这种情况。或者,您可能必须使用某种形式的 IPC 来包装您的意图并将其发送回 Activity。对于这个罕见的用例,我们使用RxBus 模式。替代选项是LocalBroadcastManager
和EventBus by GreenRobot。希望这可以帮助您开始使用替代解决方案。如果您有任何问题,请告诉我。
【讨论】:
【参考方案2】:例外是因为你可能没有覆盖 onContextItemSelected 方法。你必须覆盖 onContextItemSelected() 如下:
@Override
public boolean onContextItemSelected(MenuItem item)
startActivity(item.getIntent());
return true;
希望这会对你有所帮助。
【讨论】:
这就是我在我的问题中所说的 - 这是一种方法,但它过去无需自定义onContextItemSelected
即可工作。我试图避免它,因为上下文菜单是由与活动无关的类填充的。【参考方案3】:
你可以试试
@Override
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo)
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
MenuItem item = menu.add(menuItemText);
item.setIntent(intent);
我是 android studio 应用程序的新手,所以我不确定是否可以工作。
【讨论】:
以上是关于如何在 ContextMenu 中使用 MenuItem.setIntent()的主要内容,如果未能解决你的问题,请参考以下文章
如何在 ContextMenu 中使用 MenuItem.setIntent()
如何在动态创建的 ContextMenu 中添加水平分隔符?
如何将 ContextMenu 与 NavigationLink 一起使用?