如何在 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中添加水平分隔符?

如何将 ContextMenu 与 NavigationLink 一起使用?

WPF:如何设置或禁用 TextBox 的默认 ContextMenu

如何在 SwiftUI 中将 DatePicker 放入 ContextMenu