-
why
在日常開發(fā)過程中,有時(shí)候會(huì)遇到需要在app中嵌入網(wǎng)頁既峡,此時(shí)使用WebView實(shí)現(xiàn)效果羡榴,但在默認(rèn)情況下是無法點(diǎn)擊圖片查看大圖的,更無法保存圖片运敢。本文將就這一系列問題的實(shí)現(xiàn)進(jìn)行說明校仑。
這里面主要還是用到了android原生和js交互的知識(shí)忠售、js添加事件的知識(shí)。
1迄沫、首先在andorid的頁面中獲取到html的字符串(bean.getContent())稻扬,然后在調(diào)用公共方法去獲取到網(wǎng)頁中的所有圖片數(shù)組集合。之后就是android原生與js交互的規(guī)則了羊瘩,如你所見泰佳,此處不再詳細(xì)介紹。
//這兩行copy出來尘吗,這個(gè)變量是WebView設(shè)置和js交互時(shí)設(shè)置的名稱逝她,可以隨意起,js調(diào)用的時(shí)候也用這個(gè)就可以了
public static final String JSCALLJAVA= "jsCallJavaObj";
private String method = CommonUtil.JSCALLJAVA;
String[] imgs = JqStrUtil.returnImageUrlsFromHtml(bean.getContent());
web_course.addJavascriptInterface(new ImageJavascriptInterface(this,imgs), method);
web_course.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
CommonUtil.setWebImageClick(view,method);
}
});
獲取圖片數(shù)組的方法睬捶,通過正則匹配來獲惹稹:
public static 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("http://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會(huì)通過之前設(shè)置的名稱method來調(diào)用到其中的方法
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.webkit.JavascriptInterface;
/**
* WebView與android交互的接口設(shè)置實(shí)現(xiàn)類
* 1侧戴、可接口然后具體實(shí)現(xiàn)宁昭,然后在webview設(shè)置時(shí)具體實(shí)現(xiàn)
* 2、也可以直接實(shí)現(xiàn)酗宋,這樣在同樣需求的地方就可以直接復(fù)用了
* Created by dl on 2018/8/9.
*/
public class ImageJavascriptInterface {
private Context context;
private String[] imageUrls;
public ImageJavascriptInterface(Context context, String[] imageUrls) {
this.context = context;
this.imageUrls = imageUrls;
}
//java回調(diào)js代碼积仗,不要忘了@JavascriptInterface這個(gè)注解,不然點(diǎn)擊事件不起作用
@JavascriptInterface
public void openImage(String img,int pos) {
Intent intent = new Intent(context, PreviewImgActivity.class);//改為你要跳轉(zhuǎn)的頁面
//具體要傳遞的參數(shù)自行傳遞即可
intent.putExtra("currentItem",String.valueOf(pos));
Bundle bundle = new Bundle();
bundle.putStringArray("imgUrls",imageUrls);
intent.putExtras(bundle);
context.startActivity(intent);
}
}
(2)
這段代碼是在onPageFinished網(wǎng)頁加載完成之后設(shè)置的蜕猫,其中主要是添加了一段js代碼寂曹,只有在網(wǎng)頁加載完成之后,才能從dom中獲取所有的img節(jié)點(diǎn)也就是圖片回右。至于本身前端寫的html中并沒有給img添加點(diǎn)擊的事件隆圆,所以我們來動(dòng)態(tài)給他添加進(jìn)去。
一般h5和原生交互翔烁,這段代碼可以直接h5來寫渺氧,你將你設(shè)置的java方法和起的名字告訴h5讓其寫進(jìn)去就可以(具體到下面代碼中就是method和openImage方法)
/**
* 設(shè)置網(wǎng)頁中圖片的點(diǎn)擊事件
* @param view
*
*/
public static 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].onclick=function(){" +
"window."+method+".openImage(this.src,this.pos);" +
"}}})()";
view.loadUrl(jsCode);
}
上面代碼還需要一點(diǎn)說明:就是傳遞當(dāng)前圖片的位置問題,直接傳i是不行的蹬屹,好像有什么閉包的問題侣背,我查詢的時(shí)候也有一個(gè)網(wǎng)友對此作了很詳細(xì)的說明和解決方案的提供,傳送門慨默,我們這里采用的是給他設(shè)置一個(gè)屬性來解決
這里我最初想通過這里把圖片也賦值給一個(gè)屬性贩耐,然后將圖片數(shù)組傳到j(luò)ava的方法參數(shù)中,但是無論是用了閉包還是設(shè)置屬性厦取,java那邊總是接受不到潮太,這個(gè)疑問我至今不解,所以有知道的小伙伴兒還請不吝賜教,感激不盡啊铡买。