WebView手机屏幕(图片适应屏幕的宽度)适配的多种方式

混合开发中经常使用到WebView,适配如果前端做就省事了,自己做的话需要做适配

需求

1、详情页面包含js Html字符串,需要展示

可能存在的问题

如果包含图片的话,可能会出现图片尺寸不匹配的情况。

原来的样子

Android RecyclerView高度随Item自适应 android webview 图片自适应_webview

匹配之后的效果图

Android RecyclerView高度随Item自适应 android webview 图片自适应_webview_02

基本解决方法

1、可以通过设置WebView的相关Setting完成页面的适配,但是存在问题是,这种的适配可以达到WebView的宽度适应手机屏幕宽度。

private void initWebView(String str) {
        WebSettings webSettings = webview.getSettings();
        webSettings.setJavaScriptEnabled(true);
        //等比例缩放
        webSettings.setUseWideViewPort(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        webSettings.setSupportZoom(true);
        //SMALLEST(50%),SMALLER(75%),NORMAL(100%),LARGER(150%),LARGEST(200%);
        webSettings.setTextSize(WebSettings.TextSize.SMALLER);
        webview.getSettings().setTextZoom(100);
        webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.d(TAG, "onPageFinished");
            }
        });
        webview.loadData(str, mimeType, encoding);
    }

出现的效果图是这样的:

Android RecyclerView高度随Item自适应 android webview 图片自适应_webview

以上方法可以设置整体适应手机屏幕,但如果是图片与文字混排,图片大小不一,则会出现问题,文字不能到头就换行了,左右仍然可以滑动,无法适配图片,以下方法可以解决图片的适配主要思路:替换js代码中的图片的大小设置

1、代码动态替换标签

public void getNewHtmlText(String html){
	//替换更改
	 String str = html.replace("<img", "<img style=\"display: block;max-width:100%;\"");
	 return str;
}

2、代码动态注入JS方法

给WebView设置自己的WebViewClient,重写onPageFinished方法,在页面加载完成之后,运行注入的JS方法

webview.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                Log.d(TAG, "onPageFinished");
				reloadJS();
            }
        });
private void reloadJS(){
        webview.loadUrl("javascript:(function(){"
                //将DIV元素中的外边距和内边距设置为零,防止网页左右有空隙
                +" var divs = document.getElementsByTagName(\"div\");"
                +" for(var j=0;j < divs.length;j++){"
                +"  divs[j].style.margin=\"0px\";"
                +"  divs[j].style.padding=\"0px\";"
                +"  divs[j].style.width=document.body.clientWidth-10;"
                +" }"
                +" var imgs = document.getElementsByTagName(\"img\"); "
                +"  for(var i=0;i < imgs.length;i++)"
                +"      {"//过滤掉GIF图片,防止过度放大后,GIF失真
                +"    var vkeyWords=/.gif$/;"
                +"        if(!vkeyWords.test(imgs[i].src)){"
                +"        var hRatio="+(getScreenWidthPX()-DipPxutil.dip2px(this,30))+"/imgs[i].width;"
                +"        imgs[i].height= imgs[i].height*hRatio;"//通过缩放比例来设置图片的高度
                +"        imgs[i].width="+(getScreenWidthPX()-DipPxutil.dip2px(this,30))+";"//设置图片的宽度
                +"        }"
                +"}"
                +"})()");
    }

3、引入jsoup完成属性的替换

jsoup是一个很好的开源项目,可以解析操作JS,引入也非常简单,点击此处直接去下载jar包,也可以使用Gradle集成,添加以下代码到app -----build.gradle:

compile 'org.jsoup:jsoup:1.11.3'

Android studio 3.0以上添加以下引用:

implementation 'org.jsoup:jsoup:1.11.3'

将html文本内容中包含img标签的图片,宽度变为屏幕宽度,高度根据宽度比例自适应

String newContent = getNewContent(str);
        webview.loadData(newContent, mimeType, encoding);
public static String getNewContent(String htmltext){
        try {
            Document doc= Jsoup.parse(htmltext);
            Elements elements=doc.getElementsByTag("img");
            for (Element element : elements) {
                element.attr("width","100%").attr("height","auto");
            }
            return doc.toString();
        } catch (Exception e) {
            return htmltext;
        }
    }

最终的效果是这样的(完成图片适配):

Android RecyclerView高度随Item自适应 android webview 图片自适应_图片适配_04

示例展示

String htmlText = "<!DOCTYPE html> 
<html> 
<head> 
<meta charset="utf-8" /> 
<title>图片插入html 在线演示 www.divcss5.com</title> 
</head> 
 
<body> 
<p>原始大图片</p> 
<p> 
<img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=2116167324,1582233854&fm=11&gp=0.jpg" /> 
</p> 
<p>改小图片</p> 
<p> 
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547551786322&di=f60835f88cbb21a117349cabd06ca6c6&imgtype=0&src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F0122e4578f37050000018c1bff84ce.jpg%401280w_1l_2o_100sh.jpg"/> 
</p> 
<p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p>
<p>改大图片</p> 
<p> 
<img src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547551786321&di=949ecb5be73a0a7a37b6da9878177a6b&imgtype=0&src=http%3A%2F%2Fc.hiphotos.baidu.com%2Fimage%2Fpic%2Fitem%2F1ad5ad6eddc451da1b8e0aabbdfd5266d0163271.jpg"/> 
</p> 
<p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p><p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p><p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p><p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p><p>答:1、三者的定义不同: 艺人,自古以来,泛指有才艺、有才艺者,也用于身份自称,作为职业,它与文人有一个规范的叫法,即“文化艺术工作者”(文艺工作者)。 演员,指专职演出,或在表演艺术中扮演某个角色的人物。演员也是指参加戏曲、戏剧、电视</p>
</body> 
</html> ";
private String mimeType = "text/html";
private String encoding = "utf-8";

public void initWebView(){
	//webview.loadData(htmlText, mimeType, encoding);
	String newContent = getNewContent(htmlText);
	webview.loadData(newContent, mimeType, encoding);
}