转载请标明出处:
http://blog.csdn.net/xuehuayous/article/details/52757204
本文出自:【Kevin.zhou的博客】
前言:在Android开发中WebView加载网页,网页的适配应该是前端来处理的,毕竟客户端的对网页的控制是有限的。但是如果有一个本地的网页而且该网页的body
是固定宽度的,让我们去适配所有设备还是比较头疼的,当然这种应用场景是很罕见的,尽管如此我们还是讨论下该问题。
通常的网页适配
// 设置加载进来的页面自适应手机屏幕
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
一般情况下客户端只需要设置如上两行就可以了,当然这两行可以解决绝大部分网页的适配问题。第一行就是设置WebView支持viewpoart,第二行是设置网页超过屏幕宽度时重新布局为屏幕宽度。
如果body
设置了确切值
尽管这种在前段开发中是要极力避免的,但有时候为了方便开发还是采用了这种方式。
这里可以采用获取body
的值然后根据WebView控件的宽度与body
的宽度计算一个比例,然后设置给网页设置一个缩放比例。
JS
获取body
宽度
- 定义
JS
接口
class HTMLWidthInterface {
@JavascriptInterface
public void getContentWidth(String value) {
if (value != null) {
int bodyWidth = Integer.parseInt(value);
}
}
}
- 设置网页加载后调用
JS
接口返回body
宽度
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new HTMLWidthInterface(), "HTMLWidth");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
mWebView.loadUrl("javascript:window.HTMLWidth.getContentWidth(document.body.offsetWidth);");
}
});
计算缩放比例
private void htmlAdjustWithPageWidth(float bodyWidth, String html, WebView webView) {
// 计算要缩放的比例
DisplayMetrics metric = new DisplayMetrics();
((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
float density = metric.density; // 屏幕密度
float scale = webView.getMeasuredWidth() / density / bodyWidth;
String insertText = "<meta name=\"viewport\" content=\"width="+ bodyWidth +"px initial-scale="+ scale
+ ", minimum-scale=0.1, maximum-scale=10.0, user-scalable=no\"/>";
insertBehindText(new File(html), "<head>", insertText);
}
在HTML插入viewpoart
信息
/**
* 在指定文本之后插入一段文本
*
* @param file
* @param targetStr
* @param insertStr
* @return void:
* @version 1.0
* @date 2015-9-2
* @Author zhou.wenkai
*/
public void insertBehindText(File file, String targetStr, String insertStr) {
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
bufr = new BufferedReader(isr);
StringBuffer buf = new StringBuffer();
String line = null;
while ((line = bufr.readLine()) != null) {
// 保存原文本
buf = buf.append(line);
// 保存要插入文本
if(line.contains(targetStr)) {
buf.append(insertStr);
}
// 添加换行符号
buf = buf.append(System.getProperty("line.separator"));
}
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
bufw = new BufferedWriter(osw);
bufw.write(buf.toString());
bufw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufr != null) {
bufr.close();
}
if(bufw != null) {
bufw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
源码
public class MainActivity extends AppCompatActivity {
private final static String TAG = "WebViewContentWidth";
private WebView mWebView;
String path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK01/第一节_自我测试1.html";
// path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK02/首页.html";
// path = Environment.getExternalStorageDirectory().getPath() + "/temp/HYLNK03/home.html";;
Context mContext;
@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = this;
mWebView = (WebView) this.findViewById(R.id.main_act_wv);
// 设置不可缩放
mWebView.getSettings().setBuiltInZoomControls(false);
mWebView.getSettings().setSupportZoom(false);
mWebView.getSettings().setDisplayZoomControls(false);
// 设置支持屏幕适配
mWebView.getSettings().setUseWideViewPort(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new HTMLWidthInterface(), "HTMLWidth");
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
mWebView.loadUrl("javascript:window.HTMLWidth.getContentWidth(document.body.offsetWidth);");
}
});
mWebView.loadUrl("file://" + path);
}
class HTMLWidthInterface {
@JavascriptInterface
public void getContentWidth(String value) {
if (value != null) {
int bodyWidth = Integer.parseInt(value);
boolean hasChanged = isContainsText(new File(path), "<meta name=\"viewport\"");
if(!hasChanged) {
htmlAdjustWithPageWidth(bodyWidth, path, mWebView);
mWebView.loadUrl("file://" + path);
}
}
}
}
private void htmlAdjustWithPageWidth(float bodyWidth, String html, WebView webView) {
// 计算要缩放的比例
DisplayMetrics metric = new DisplayMetrics();
((Activity)mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
float density = metric.density; // 屏幕密度
float scale = webView.getMeasuredWidth() / density / bodyWidth;
String insertText = "<meta name=\"viewport\" content=\"width="+ bodyWidth +"px initial-scale="+ scale
+ ", minimum-scale=0.1, maximum-scale=10.0, user-scalable=no\"/>";
insertBehindText(new File(html), "<head>", insertText);
}
/**
* 在指定文本之后插入一段文本
*
* @param file
* @param targetStr
* @param insertStr
* @return void:
* @version 1.0
* @date 2015-9-2
* @Author zhou.wenkai
*/
public void insertBehindText(File file, String targetStr, String insertStr) {
BufferedReader bufr = null;
BufferedWriter bufw = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
bufr = new BufferedReader(isr);
StringBuffer buf = new StringBuffer();
String line = null;
while ((line = bufr.readLine()) != null) {
// 保存原文本
buf = buf.append(line);
// 保存要插入文本
if(line.contains(targetStr)) {
buf.append(insertStr);
}
// 添加换行符号
buf = buf.append(System.getProperty("line.separator"));
}
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
bufw = new BufferedWriter(osw);
bufw.write(buf.toString());
bufw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufr != null) {
bufr.close();
}
if(bufw != null) {
bufw.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 检查是否包含制定文本
*
* @param file
* @param containsStr
* @return
* @return boolean:
* @version 1.0
* @date 2015-10-28
* @Author zhou.wenkai
*/
public boolean isContainsText(File file, String containsStr) {
BufferedReader bufr = null;
try {
InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");
bufr = new BufferedReader(isr);
String line;
while ((line = bufr.readLine()) != null) {
if(line != null && line.contains(containsStr)) {
return true;
}
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(bufr != null) {
bufr.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
}