欢迎来到山村网

Android WebView如何自定义长按收藏/分享选中文本

2019-03-09 12:57:48浏览:432 来源:山村网   
核心摘要:效果图(1.3M)一、前言** 戳这里可以去DEMO,来吧 **相信刚接触android不久的同志们,在面对产品提出的 :自定义WebView页面中

效果图(1.3M)

Android WebView如何自定义长按收藏/分享选中文本 山村

一、前言

** 戳这里可以去DEMO,来吧 **

相信刚接触android不久的同志们,在面对产品提出的 :

“自定义WebView页面中,长按文本的弹出选项、点击选择后,分享、转发、收藏选择文本”

这样的需求时,第一反应大部分是:这是系统行为,如果实现需要在web端实现。

但是web端实现的局限性太大,曾经也有过监听系统粘贴板,在用户点击复制的时候实现其他的逻辑,但是这样用户体验不好,所以自定义WebView中长按的弹出菜单,并在点击时返回选中文本的小控件闪亮登场┏ (^ω^)=。

二、自定义长按弹出菜单

这一步实现其实很简单,首先创建一个CustomActionWebView继承系统WebView,然后重写下面两个方法。

这两个方法会在用户长按选择web文本时,在弹出菜单前被调用。它们之间的区别在于,第一个方法的菜单弹出方式,指定了默认的type。我们并不关心弹出的item类型是什么,我们只需要拦截下来ActionMode,然后返回我们自己的自定义ActionMode即可。

@Overridepublic ActionMode startActionMode(ActionMode.Callback callback) {  ActionMode actionMode = super.startActionMode(callback);  return resolveActionMode(actionMode);}@Overridepublic ActionMode startActionMode(ActionMode.Callback callback, int type)   ActionMode actionMode = super.startActionMode(callback, type);  return resolveActionMode(actionMode);}

这里我们所做的事是:

1、把原本的actionMode对象保存到mActionMode中。

2、清空原本actionMode中的MenuItem。

3、添加我们自定义的item到actionMode中。

4、重定义每个menuItem的点击事件。

5、在点击事件中通过执行js,获取选中文本。

6、通过上面保存的 mActionMode,释放弹出菜单(不释放会内存泄漏)。

7、返回新填充的actionMode给系统。

private ActionMode resolveActionMode(ActionMode actionMode) {  if (actionMode != null) {    final Menu menu = actionMode.getMenu();    mActionMode = actionMode;    menu.clear();    for (int i = 0; i < mActionList.size(); i++) {      menu.add(mActionList.get(i));    }    for (int i = 0; i < menu.size(); i++) {      MenuItem menuItem = menu.getItem(i);      menuItem.setonMenuItemClickListener(new Item.onMenuItemClickListener() {        @Override        public boolean onMenuItemClick(MenuItem item) {          getSelectedData((String) item.getTitle());          releaseAction();          return true;        }      });    }  }  mActionMode = actionMode;  return actionMode;}

实现效果

三、获取选中文本

光自定义菜单,拿不到选中文本也没意义,那么如何获取选中文本呢?这里如果不转个弯,还真会在南墙在撞死( ̄^ ̄)ゞ,所以,我们伟大的js就出现了。

首先,我们自定义一个接口,用于监听js方法,其中@JavascriptInterface是关键的所在, 在callback中获取js端返回的数据。

然后将这个接口,在CustomActionWebView中add进去(一般是在初始化和页面加载完成时都add一次),并指定js端调用的接口名称为“ JSInterface”。(ps:别忘了开始webview的js允许哦。)

public void linkJSInterface() {  addJavascriptInterface(new ActionSelectInterface(this), "JSInterface");}···private class ActionSelectInterface {  CustomActionWebView mContext;  ActionSelectInterface(CustomActionWebView c) {    mContext = c;  }  @JavascriptInterface  public void callback(final String value, final String title) {    if(mActionSelectListener != null) {      mActionSelectListener.onClick(title, value);    }  }}

最后在点击时,通过执行js来获取web中选中的文本。在上面自定义菜单中第5项,点击menu时,执行下方js代码,便可以把选中的item和文本,回调到上面的接口中的callback。

熟悉js的小伙伴已经看出来吧:

其实就是定义了一个js的function,然后在webview中执行这个方法。

定义的这个名为function getSelectedText()的js方法,有两个变量:txt和title。

title是从原生中传入的item名字,txt是通过window去获取web中选中的文本。

最后回到上面我们注册的js方法名JSInterface,通过它的callback方法,将文本和name返回到原生代码callback中。
根据版本不同,执行js方法的接口也不一样。

private void getSelectedData(String title) {  String js = "(function getSelectedText() {" +      "var txt;" +      "var title = "" + title + "";" +      "if (window.getSelection) {" +      "txt = window.getSelection().toString();" +      "} else if (window.document.getSelection) {" +      "txt = window.document.getSelection().toString();" +      "} else if (window.document.selection) {" +      "txt = window.document.selection.createRange().text;" +      "}" +      "JSInterface.callback(txt,title);" +      "})()";  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {    evaluateJavascript("javascript:" + js, null);  } else {    loadUrl("javascript:" + js);  }}

四、最后

既然自定义item实现了,点击和选择文本返回也实现了,在callback中,你就可以愉悦的收藏,或者分享你所选中的文本啦(◑),操作一气呵成,有没有被惊艳到呢?

如果感兴趣的,可以下载demo看下,同时CustomActionWebView也封装好了远程依赖,欢迎使用。

https://github.com/CarGuo/CustomActionWebView

(责任编辑:豆豆)
下一篇:

linux 的date命令及系统时间设置

上一篇:

路由器怎么设置防蹭网

  • 信息二维码

    手机看新闻

  • 分享到
打赏
免责声明
• 
本文仅代表作者个人观点,本站未对其内容进行核实,请读者仅做参考,如若文中涉及有违公德、触犯法律的内容,一经发现,立即删除,作者需自行承担相应责任。涉及到版权或其他问题,请及时联系我们 xfptx@outlook.com