WebView自定义长按选择,实现收藏/分享选中文本。
2017-06-19 09:18
495 查看
Hello,大家吼,吾就是那个挖坑不止的郭小喵,不管有没有想我(˶‾᷄ ⁻̫ ‾᷅˵)的,这次就分享快速实现一个自定义WebView的小控件吧,效果如下图,废话不多说,我们直接开撸吧。
(PS : ╮(╯▽╰)╭如果你翻一翻我过去的文章,你会发现90%的开场白,前几个问候语都是一样的。)
相信刚接触android不久的同志们,在面对产品提出的 :
这样的需求时,第一反应大部分是:这是系统行为,如果实现需要在web端实现。
但是web端实现的局限性太大,曾经也有过监听系统粘贴板,在用户点击复制的时候实现其他的逻辑,但是这样用户体验不好,所以自定义WebView中长按的弹出菜单,并在点击时返回选中文本的小控件闪亮登场┏ (^ω^)=。
这两个方法会在用户长按选择web文本时,在弹出菜单前被调用。它们之间的区别在于,第一个方法的菜单弹出方式,指定了默认的type。我们并不关系弹出的item类型是什么,我们只需要拦截下来ActionMode,然后返回我们自己的自定义ActionMode即可。
这里我们所做的事是:
* 1、把原本的actionMode对象保存到mActionMode中。
* 2、清空原本actionMode中的MenuItem。
* 3、添加我们自定义的item到actionMode中。
* 4、重定义每个menuItem的点击事件。
* 5、在点击事件中通过执行js,获取选中文本。
* 6、通过上面保存的* mActionMode*,释放弹出菜单(不释放会内存泄漏)。
* 7、返回新填充的actionMode给系统。
首先,我们自定义一个接口,用于监听js方法,其中
然后将这个接口,在CustomActionWebView中add进去(一般是在初始化和页面加载完成时都add一次),并指定js端调用的接口名称为“ JSInterface”。(ps:别忘了开始webview的js允许哦。)
最后在点击时,通过执行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方法的接口也不一样。
如果感兴趣的,可以下载demo看下,同时CustomActionWebView也封装好了远程依赖,欢迎使用。
https://github.com/CarGuo/CustomActionWebView
(PS : ╮(╯▽╰)╭如果你翻一翻我过去的文章,你会发现90%的开场白,前几个问候语都是一样的。)
一、前言
[b]* 戳这里可以去DEMO,来吧 * [/b]相信刚接触android不久的同志们,在面对产品提出的 :
“自定义WebView页面中,长按文本的弹出选项、点击选择后,分享、转发、收藏选择文本”
这样的需求时,第一反应大部分是:这是系统行为,如果实现需要在web端实现。
但是web端实现的局限性太大,曾经也有过监听系统粘贴板,在用户点击复制的时候实现其他的逻辑,但是这样用户体验不好,所以自定义WebView中长按的弹出菜单,并在点击时返回选中文本的小控件闪亮登场┏ (^ω^)=。
二、自定义长按弹出菜单
这一步实现其实很简单,首先创建一个CustomActionWebView继承系统WebView,然后重写下面两个方法。这两个方法会在用户长按选择web文本时,在弹出菜单前被调用。它们之间的区别在于,第一个方法的菜单弹出方式,指定了默认的type。我们并不关系弹出的item类型是什么,我们只需要拦截下来ActionMode,然后返回我们自己的自定义ActionMode即可。
@Override public ActionMode startActionMode(ActionMode.Callback callback) { ActionMode actionMode = super.startActionMode(callback); return resolveActionMode(actionMode); } @Override public 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给系统。
/** * 处理item,处理点击 * @param 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"); } ··· /** * js选中的回调接口 */ 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方法的接口也不一样。
/** * 点击的时候,获取网页中选择的文本,回掉到原生中的js接口 * @param title 传入点击的item文本,一起通过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.VERSI 9f9f ON_CODES.KITKAT) { evaluateJavascript("javascript:" + js, null); } else { loadUrl("javascript:" + js); } }
四、最后
既然自定义item实现了,点击和选择文本返回也实现了,在callback中,你就可以愉悦的收藏,或者分享你所选中的文本啦(◐‿◑),操作一气呵成,有没有被惊艳到呢?如果感兴趣的,可以下载demo看下,同时CustomActionWebView也封装好了远程依赖,欢迎使用。
https://github.com/CarGuo/CustomActionWebView
相关文章推荐
- WebView自定义长按选择,实现收藏/分享选中文本
- Android WebView自定义长按选择实现收藏/分享选中文本功能
- 安卓webview长按分享,长按选择,长按复制,仿好奇心日报长按分享自定义弹窗的实现
- 自定义webview长按文本弹出选项,并且点击后返回选项与所选中的文本
- android webview实现文本选择
- android 腾讯微博分享功能实现及自定义webview认证
- Android自定义的webView——可实现的网页文本的复制
- Android TextView 自定义识别文本中的超链接并打开自身WebView(按照微信效果实现)
- android 腾讯微博分享功能实现及自定义webview认证
- Android 自定义View修炼-【2014年最后的分享啦】Android实现自定义刮刮卡效果View
- 新浪微博插入话题后部分文字选中的js实现(控制鼠标指针位置/自动选择指定文本)
- android webview 调用js实现图像选择并上传
- ProgressBar+WebView实现自定义浏览器
- css 选择后更改文字背景 CSS3 实现改变默认文本选中的颜色
- 自定义RecycleView实现TV应用上的item焦点获取以及设置当前选中的item居中
- 【Android】 切换Webview与自定义的界面实现
- 分享一个实现图片圆角,圆的自定义的ImageView,尽可能少的减少内存消耗。
- 如何实现自定义的android WebView错误页
- Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView
- 自定义TextView实现选择A,B,C,D