在Android中的WebView中覆盖默认的文本选择上下文操作栏

27

我想覆盖现有的默认上下文操作栏 (CAB) 以用于文本选择。我的意思是,当在 webview 上选择某些文本时,我想显示自己的 CAB,并使用自己的按钮。我尝试使用 Android 文档实现 CAB,但 OnLongClickListener 不能捕获 webview 中的文本选择事件。哪个事件可以捕获文本选择?是否可能隐藏默认 CAB 并在文本选择时显示我的 CAB?

childWebView.setOnLongClickListener(new OnLongClickListener() {
        @Override
     // Called when the user long-clicks on someView
        public boolean onLongClick(View view) {
            if (mActionMode != null) {
                return false;
            }

            // Start the CAB using the ActionMode.Callback defined above
            mActionMode = startActionMode(mActionModeCallback);
            view.setSelected(true);
            return true;
        }
    });

你找到那个问题的解决方案了吗,Karka? - Elyes Jlassi
到目前为止有任何解决方案吗? - sanjeev
我也在寻找解决方案。 - sachin003
@matiash,请在创建新标签时小心。我们已经有一个用于Android上下文操作栏的标签了。 - Charles
@Charles 对不起,你说得完全正确。我在重新标记一些问题时找到了它。这就是为什么我停下来的原因。 :/ 但是所有的安卓标签都应该有 android- 前缀吗? - matiash
显示剩余2条评论
2个回答

9
我已经解决了这个问题。我也遇到了这个问题,但在网上找不到任何解决方案。
所以,如果你设置一个长按监听器,Webview 就会完全停止显示选择。深入研究 Webview 代码后,我发现它正在调用 WebView 的 startRunMode 方法,并传递 SelectActionCallbackMode 类的实例。
我只需扩展 Webview 类并重写 startRunMode 方法,像这样:
public ActionMode startActionMode(ActionMode.Callback callback) 
{
    actionModeCallback = new CustomizedSelectActionModeCallback();
    return super.startActionMode(actionModeCallback);
}

这迫使Webview显示我的回调而不是Webview的默认回调。这确保了选择操作像以前一样顺畅,并且每次进行选择时都显示了我的操作栏。唯一的注意事项是我要自己编写代码来取消操作栏。
测试通过4.1、4.2和4.3设备。
希望这能有所帮助。

但是您无法从Webview中获取所选文本。此外,在我的实现中,有时会在Kitkat Webview中使用此方法时出现内部错误。 - Frank
@Frank 你可以通过 JavaScript (window.getSelection().toString()) 获取所选文本。我还没有在 KitKat 上尝试过,会尝试并查看问题。 - Pulkit Gupta
你在4.4版本上有没有运气好一点?我也做了同样的事情,但是如果选择有任何改变,应用程序在选择一个操作后会崩溃。 - Sean Beach
它在我的4.4上完美运行。此外,在4.4上,无需手动解雇CAB。它会被Android自动隐藏。 - Pulkit Gupta
@PulkitGupta:如何在文本选择时打开自定义对话框,而不是默认的复制对话框? - Anand Savjani
显示剩余2条评论

1

官方文档Selection | Android Developers指出:

选择 CAB 操作

您可以决定在 CAB 中显示哪些操作和元素。使用 操作栏模式 中的指南来决定将哪些项目上升到顶层并将哪些项目移动到操作溢出。

动态调整 CAB 操作 在大多数情况下,您需要在用户添加更多选项时动态地调整 CAB 操作。适用于单个选定数据项的操作不一定适用于相同类型的多个选定数据项。

不幸的是,引用中包含的链接也只提供一般信息,而没有详细的内容。更糟糕的是,它链接回Selection | Android Developers页面。

进一步查看后,我找到了Lars Vogel的本教程。引用如下(格式由我调整):

上下文操作模式会激活一个临时的ActionBar,覆盖应用程序ActionBar在特定子任务的持续时间。

通常通过选择项目或长按项目来激活上下文操作模式。

要实现这一点,请在视图或您的活动上调用startActionMode()方法。此方法获取一个ActionMode.Callback对象,该对象负责上下文ActionBar的生命周期。

您还可以通过registerForContextMenu(view)方法将上下文菜单分配给View。如果用户“长按”视图,也会激活上下文菜单。每次激活上下文菜单时都会调用onCreateContextMenu()方法,因为上下文菜单在使用后被丢弃。您应该优先考虑使用上下文操作模式而不是上下文菜单。

最突出的参考资料提到,我们可以使用 registerForContextMenu(view) 来创建自己的菜单。我找到了 this answer,由 J. Pablo Fernández 提供了一个代码示例,演示如何应用自己的 CAB。注册新的上下文菜单应该会覆盖任何默认菜单,但我不确定。由于我目前无法测试这个功能,所以很高兴听到这是否解决了您的问题。

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