Android WebView开发之自定义WebView工具框
作者:红日666 发布时间:2023-01-12 13:41:43
标签:Android,WebView,工具框
附GitHub源码:WebViewExplore
先看图:
在WebView页面长按时会弹出一个复制框,但如果里面的item不是我们想要的或者想自定义,那么可以通过覆盖WebView的 startActionMode 方法来实现:
/**
* 长按弹出ActionMode菜单样式
* @param callback
* @param type
* @return
*/
@Override
public ActionMode startActionMode(Callback callback, int type) {
Logger.d(TAG, "startActionMode--callback:" + callback + " type:" + type);
ActionMode actionMode = super.startActionMode(callback, type);
return resolveActionMode(actionMode);
}
private ActionMode resolveActionMode(ActionMode actionMode) {
if (actionMode != null) {
final Menu menu = actionMode.getMenu();
mActionMode = actionMode;
//清除系统自定item选项
menu.clear();
/**
* 为菜单item重新赋值
*/
for (int i = 0; i < mActionList.size(); i++) {
menu.add(mActionList.get(i));
//可以为每个item添加icon
//menu.getItem(i).setIcon(R.drawable.ic_launcher);
}
for (int i = 0; i < menu.size(); i++) {
MenuItem menuItem = menu.getItem(i);
/**
* 新添item的点击事件【可根据不同个item点击事件,来进行相关的业务处理】
*/
menuItem.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
Logger.d(TAG, item.getTitle().toString());
getSelectedData((String) item.getTitle());
releaseAction();
return true;
}
});
}
}
mActionMode = actionMode;
return actionMode;
}
上面的mActionList是早已经在该控件的构造方法调用时添加了所需的item:
private void initData() {
mActionList = new ArrayList<>();
//扩选
mActionList.add(GlobalConstant.ENLARGE);
//复制
mActionList.add(GlobalConstant.COPY);
//分享
mActionList.add(GlobalConstant.SHARE);
}
这里拿"复制"事件举例,通过如下native调用该Js的代码的方式可以获取当前所文本框所选中的文本:
/**
* Android调用JS的代码方式有2种:
* 1、通过WebView的loadUrl()
* 2、通过WebView的evaluateJavaScript()
* <p>
* 点击的时候,获取网页中选择的文本,回掉到原生中的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.VERSION_CODES.KITKAT) {
evaluateJavascript("javascript:" + js, new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
//此处为js返回结果
Logger.d(TAG, "value:" + value);
}
});
} else {
loadUrl("javascript:" + js);
}
}
点击复制按钮就可以将我们选中的文本赋值到上述js脚本中的 'txt' 变量中,但是如何传递到native呢,这就用到了 WebView与Native的交互 章节介绍的JS调用Native的方法1,这里再说明一下:
在该控件的构造方法中早已映射了原生方法接口:
private void linkJSInterface() {
//Js调用native的方式一
addJavascriptInterface(new ActionSelectInterface(this), "JSInterface");
}
JSInterface 对应的映射接口 ActionSelectInterface 实现如下:
/**
* JS调用android原生方法1:
* 通过WebView的addJavascriptInterface()进行对象映射
*/
public class ActionSelectInterface {
private ActionWebView mActionWebView;
public ActionSelectInterface(ActionWebView actionWebView) {
mActionWebView = actionWebView;
}
@JavascriptInterface
public void callback(final String value, final String title) {
Logger.d(TAG, "currentThread:" + Thread.currentThread());
post(new Runnable() {
@Override
public void run() {
if (mActionSelectListener != null) {
mActionSelectListener.onClick(title, value);
}
}
});
}
}
所以最终就可以根据上述js脚本中的 'JSInterface.callback(txt,title);‘方法的调用,来最终响应 至native类ActionSelectInterface中callback中,会收到title及复制文本value的值。
这样根据之前的监听,便可进行后续的一系列业务操作。
来源:https://blog.csdn.net/u012440207/article/details/121804509


猜你喜欢
- Springboot Aspect切面的实现今天我们来说说spring中的切面Aspect,这是Spring的一大优势。面向切面编程往往让我
- 本文实例为大家分享了Android实现轮播图片效果的具体代码,供大家参考,具体内容如下一、原理首先,将这些要轮播的图片和一些文本分别放置在不
- 如下所示:import java.security.MessageDigest;import java.security.NoSuchAlg
- C#限速下载网络文件的方法,具体如下:using System;using System.Collections.Concurrent;us
- 效果图如下:1.适用需求后台生成验证码,用于登陆验证。2. 功能实现所需控件/文件:无(普通标签)3.功能点实现思路1)前台思路:(1)前台
- 本文实例讲述了Android SQLite数据库操作方法。分享给大家供大家参考,具体如下:SQLite and AndroidSQLite简
- 哎,最近很好久没写点东西了,由于工作的原因,接触公司自己研发的底层orm框架,偶然发现该框架在调用jdbc操作的时候参考的是hibernat
- 怎么使用异步,就是用委托进行处理,如果委托对象在调用列表中只有一个方法,它就可以异步执行这个方法。委托类有两个方法
- for循环和foreach循环其实可以算得上是从属关系的,即foreach循环是可以转化成for循环,但是for循环不一定能转换成forea
- 什么是斐波那契数列?经典数学问题之一;斐波那契数列,又称黄金分割数列,指的是这样一个数列:1、1、2、3、5、8、13、21、……想必看到这
- 现阶段,我们创建了最简单的Android项目,现在在此公布github链接https://github.com/neuyu/android-
- storm操作zookeeper的主要函数都定义在命名空间backtype.storm.cluster中(即cluster.clj文件中)。
- 在一些购物商城中经常会遇到这类效果,效果图如下:先看效果图步骤一:完成对主界面main.xml的创建:<?xml version=&q
- 开源配置中心 - ApolloApollo(阿波罗)是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境、不同集群的配置,配置修改后
- 目录1. SpringCloud特点2. 分布式系统的三个指标CAP3. Eureka4. SpringCloud Demo4.1 regi
- 面对android studio Run 一次项目要等好几分钟的痛点,不得不研究一下android studio 的单元测试。其实我的目的很
- 本文介绍MediaPlayer的使用。MediaPlayer可以播放音频和视频,另外也可以通过VideoView来播放视频,虽然VideoV
- 有一种方法可以阻止父层的View截获touch事件,就是调用 getParent().requestDisallowInterceptTou
- 位操作符是对数据按二进制位进行运算的操作符。位操作是其他很多语言都支持的操作,如C、C++和Java等,C#也不例外支持位操作。注意位操作支
- 一、项目背景在实际工作中,会遇到业务比较集中的情况,随着时间推延,这部分业务关联的mysql表就会越来越大,十分臃肿。尽管在项目架构上做了读