如何修改WebView文本选中时的Contextual Action Bar为Floating Context Menu?


我想实现这种效果:
图片描述

而选中WebView的文本时,默认是这样的效果:
图片描述

跪求指点,弄好好几天了。

Android menu webview

K.O.S 8 years, 10 months ago

Update

最开始的思路:尝试侦听WebView文本选中事件以弹出自定义的上下文菜单,失败!
我找到了一个开源代码: BTAndroidWebViewSelection
有人把这份源码封装成了库:
Support library for text selection on Android WebView. (forked from BTAndroidWebViewSelection)

I've Seen a lot of people trying to get user selections with a context menu working in Android web views. The problem lies in Android's use of an intermediate text view that it places between the user and the web view on selection. So the javascript in the page doesn't know what's selected.
This solution uses a javascript interface to pass touches to the page and effectively cut Android's native selection out of the equation. This has been tested from 2.2 to 4.0.3.

这应该差不多就是你想要的效果了:
图片描述

至于怎么用,就去看源码吧


最开始的思路

WebView 内长按弹出的上下文菜单是contextual action mode,也就是你贴的第2张图,看来应该是WebView默认的特性。而你贴的第1张图是floating context menu.
官方文档menus.html#context-menu

如果想改变这种默认特性,我能想到的思路是:

  • 定义一个context menu,注册给你的WebView: registerForContextMenu(View view)
    覆写context menu的两个回调函数 onCreateContextMenu() onContextItemSelected() ,以响应context menu点击事件;
    这是官方文档给出的实现floating context menu的标准步骤;
    需要说明的是这种方法实现的context menu是一个listview,可能还需要进一步自定义以实现你想要的布局;

  • 然后需要侦听到WebView文本选中的事件,以在选中文字后,调用 Activity.openContextMenu() 弹出自定义的floating context menu;
    webview并没有提供文本选中的listener,所以可能得需要继承WebView,覆写它的某些方法.


 // Step 1
// Registers a context menu to be shown for the given view.
registerForContextMenu(mWebView);

// Called when the context menu for this view is being built.
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
    getMenuInflater().inflate(R.menu.your_custom_context_menu, menu);
}

// Called whenever an item in a context menu is selected.
@Override
public boolean onContextItemSelected(MenuItem item) {
    // do your stuff to respond for menu item selected
    // ...
    return super.onContextItemSelected(item);
}

// Step 2
// 可能需要继承webview以在选中文本后弹出context menu
        ...
        // Programmatically opens the context menu for a particular view.
        openContextMenu(v);
        ...
});

但是,现在卡在了第2步上。即使覆写WebView,也达不到选中的效果,总是长按WebView就弹出来选项菜单。

steven answered 8 years, 10 months ago

Your Answer