WebView加载数据(不是加载网址)的时候,WebView的图片(可以是多张)添加点击事件

在日常开发过程中,有时候会遇到需要在app中嵌入网页,WebView加载数据(不是加载网址)的时候,此时使用WebView实现效果,但在默认情况下是无法点击图片查看大图的,更无法保存图片。本文将就这一系列问题的实现进行说明。

 

这里面主要还是用到了android原生和js交互的知识、js添加事件的知识。

1、首先在andorid的页面中获取到html的字符串(bean.getContent()),然后在调用公共方法去获取到网页中的所有图片数组集合。之后就是android原生与js交互的规则了,如你所见,此处不再详细介绍。

 

//这两行copy出来,这个变量是WebView设置和js交互时设置的名称,可以随意起,js调用的时候也用这个就可以了
String JSCALLJAVA = "jsCallJavaObj";
String method = JSCALLJAVA;
String[] imgs = returnImageUrlsFromHtml(webContent);

mWebSettings = webView.getSettings();
mWebSettings.setJavaScriptEnabled(true);
webView.addJavascriptInterface(new ImageJavascriptInterface(mContext, imgs), method);
webView.setWebViewClient(new WebViewClient() {
   
   @Override
   public void onPageStarted(WebView view, String url, Bitmap favicon) {
      super.onPageStarted(view, url, favicon);
   }
   
   @Override
   public void onPageFinished(WebView view, String url) {
      super.onPageFinished(view, url);
      
      setWebImageClick(view, method);
   }
});
String webContent=bean.getContent();
//WebView加载数据代码
webView.loadDataWithBaseURL(null, webContent, "text/html", "utf-8", null);

获取图片数组的方法,通过正则匹配来获取:

public String[] returnImageUrlsFromHtml(String htmlCode) {
   List<String> imageSrcList = new ArrayList<String>();
   Pattern p = Pattern.compile("<img\\b[^>]*\\bsrc\\b\\s*=\\s*('|\")?([^'\"\n\r\f>]+(\\.jpg|\\.bmp|\\.eps|\\.gif|\\.mif|\\.miff|\\.png|\\.tif|\\.tiff|\\.svg|\\.wmf|\\.jpe|\\.jpeg|\\.dib|\\.ico|\\.tga|\\.cut|\\.pic|\\b)\\b)[^>]*>", Pattern.CASE_INSENSITIVE);
   Matcher m = p.matcher(htmlCode);
   String quote = null;
   String src = null;
   while (m.find()) {
      quote = m.group(1);
      src = (quote == null || quote.trim().length() == 0) ? m.group(2).split("//s+")[0] : m.group(2);
      imageSrcList.add(src);
   }
   if (imageSrcList.size() == 0) {
      return null;
   }
   return imageSrcList.toArray(new String[imageSrcList.size()]);
}

接下来是android原生和js交互的代码:
(1) Java类(定义的内部类),js会通过之前设置的名称method来调用到其中的方法

class ImageJavascriptInterface {
   
   private Context  context;
   private String[] imageUrls;
   
   public ImageJavascriptInterface(Context context, String[] imageUrls) {
      this.context = context;
      this.imageUrls = imageUrls;
   }
   
   //java回调js代码,不要忘了@JavascriptInterface这个注解,不然点击事件不起作用
   @JavascriptInterface
   public void openImage(String img, int pos) {
      Log.i(TAG, "img*****" + img);
      Log.i(TAG, "pos*****" + pos);
//保存图片操作(根据需求,可能是先弹框,然后保存图片)      
initSavaPicture(img);
   }
}

(2)这段代码是在onPageFinished网页加载完成之后设置的,其中主要是添加了一段js代码,只有在网页加载完成之后,才能从dom中获取所有的img节点也就是图片。至于本身前端写的html中并没有给img添加点击的事件,所以我们来动态给他添加进去。
一般h5和原生交互,这段代码可以直接h5来写,你将你设置的java方法和起的名字告诉h5让其写进去就可以(具体到下面代码中就是method和openImage方法)

/**
 * 设置网页中图片的点击事件
 *
 * @param view
 * @param method
 */
public void setWebImageClick(WebView view, String method) {
   String jsCode = "javascript:(function(){" +
                  "var imgs=document.getElementsByTagName(\"img\");" +
                  "for(var i=0;i<imgs.length;i++){" +
                  "imgs[i].pos = i;" +
                  "imgs[i].οnclick=function(){" +
                  "window." + method + ".openImage(this.src,this.pos);" +
                  "}}})()";
   view.loadUrl(jsCode);
}

(3)这时候图片可以直接保存了,但是如果是

androidx.core.widget.NestedScrollView或者ScrollView嵌套WebView的时候,

第一次点击图片,WebView会有自动滑动一下的bug,解决这个问题。

可能是WebView抢占了焦点而导致的自动滚动,于是就在WebView的父布局(LinearLayout)加了一行:

android:descendantFocusability="blocksDescendants"

就解决了这个自动滑动一下的bug。

 

descendantFocusability有几个属性如下:

beforeDescendants:viewgroup会优先其子类控件而获取到焦点

afterDescendants:viewgroup只有当其子类控件不需要获取焦点时才获取焦点

blocksDescendants:viewgroup会覆盖子类控件而直接获得焦点

我们需要的是让父类Layout(LinearLayout)直接覆盖子类Layout(WebView)直接获取到焦点,这样WebView就不会自动滑动了。

 

 

如对此有疑问,请联系qq1164688204。

推荐Android开源项目

项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。

项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值