Android内置webkit内核的高性能浏览器,而WebView则是在这个基础上进行封装后的一个 控件,WebView直译网页视图,我们可以简单的看作一个可以嵌套到界面上的一个浏览器控件! 在 版本之后内核换成了 chrome 内核,但是 对外的API并没有更换
主要处理 对话框,网站title,icon 加载进度 等;侧重于对 内容的处理
方法 | 作用 |
---|---|
onJsAlert(WebView view,String url,String message,JsResult result) | 对js中alert对话框的处理 |
onJsConfirm(WebView view,String url,String message,JsResult result) | 对js中confirm对话框的处理 |
onJsPrompt(WebView view,String url,String message,String defaultValue,JsPromptResult result) | 对js中 Prompt对话框的处理 |
onProgressChanged(WebView view,int newProgress) | 当加载进度发生变化时调用 |
onReceivedIcon(WebView view, Bitmap icon) | 获得网页的icon |
onReceivedTitle(WebView view,String title) | 获取网页的标题 |
注意点: 在对话框处理完之后要对网页做出回应确认处理完成(
result.confirm();
)不让网页就会卡在 对话框那个地方 ,无法再次进行相应
private WebChromeClient chromeClient = new WebChromeClient(){
//网页加载进度显示
@Override
public void onProgressChanged(WebView view, int newProgress) {
Log.i(TAG, "onProgressChanged: progress="+newProgress);
if (newProgress!=100){
pb.setVisibility(View.VISIBLE);
pb.setProgress(newProgress);
}else{
pb.setVisibility(View.GONE);
}
}
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
//确认交互完成 提交结果 勿忘
result.confirm();
return true;
}
};
主要处理WebView的各种请求通知; 侧重于对浏览器本身事件重写
方法 | 作用 |
---|---|
onPageStared(WebView view,String url) | 通知主程序网页开始加载 |
onPageFinished(WebView view,String url,Bitmap favicon) | 通知主程序网页加载完毕 |
doUpdateVisitedHistory(WebView view,String url,boolean isReload) | 更新历史记录 |
onLoadResource(WebView view,String url) | 通知主程序即将加载指定url的资源 |
onScaleChanged(WebView view,float oldScale,float newScale) | WebView的缩放改变时调用 |
shouldOverrideKeyEvent(WebView view,KeyEvent event) | 控制WebView是否处理按键事件,如果返回true则处理,返回false则不处理 |
shouldOverrideUrlLoading(WebView view,String url) | 控制对新加载的url的处理;例如在本view打开,返回true说明 处理 ,返回false说明不处理; |
onReceivedError(WebView view,int errorCode,String description,String failingUrl) | 遇到不可恢复的错误信息时调用 |
注意点:
shouldOverrideUrlLoading(WebView view,String url)
在 API 21中过时; 替代方法为shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
//主要处理WebView的各种请求通知 侧重于 对 浏览器本身事件重写
private WebViewClient viewClient = new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.i(TAG, "shouldOverrideUrlLoading: url="+url);
//当打开一个新的 url 时在本view打开,不跳转至浏览器
view.loadUrl(url);
return true;
}
};
WebView相关配置的设置,比如setJavaScriptEnabled()设置是否允许JS脚本执行 部分方法如下:
方法 | 作用 |
---|---|
setUseWideViewPort(boolean enabled) | 是否支持viewPort |
setLoadWithOverviewMode(boolean enabled) | 自适应屏幕 |
setSupportZoom(boolean enabled) | 是否支持缩放 |
setBuiltInZoomControls(boolean enabled) | 目前没测试 |
setDisplayZoomControls(boolean enabled) | 是否支持缩放控件 |
setDefaultFontSize(int size) | 设置默认字体大小 |
setDefaultTextEncodingName(String encoding) | 默认字符编码可用来解决中文乱码问题 |
setJavaScriptEnabled(boolean enabled) | 是否支持js交互 |
//支持js交互
webView.getSettings().setJavaScriptEnabled(true);
//设置默认编码方式
webView.getSettings().setDefaultTextEncodingName("utf-8");
webView.getSettings().setDefaultFontSize(20);
方法 | 作用 |
---|---|
loadUrl(String url) | 加载指定的url |
loadData(String data,String mimeType,String encoding) | 加载指定的Data到WebView中.使用”data:”作为标记头,该方法不能加载网络数据.其中mimeType为数据类型如:textml,image/jpeg. encoding为字符的编码方式 |
loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) | loadData的升级版 可以以baseUrl为标准路径加载相应的文件等 |
getSettings() | 返回一个WebSettings对象,用来控制WebView的属性设置 |
setWebViewClient(WebViewClient client) | 为WebView指定一个WebViewClient对象 |
setWebChromeClient(WebChromeClient client) | 为WebView制定一个 WebChromeClient对象 |
setBackgroundColor(int color) | 设置WebView的背景颜色 |
setOnScrollChangeListener(View.OnScrollChangeListener changeListener) | 滚动条滚动监听,在API 23 加入 |
注意点: WebView 背景色 需要代码进行设置 ;xml属性不好使;
加载指定的Url loadUrl()
;
//url
webView.loadUrl("http://baidu.com");
加载网页代码 loadData()
;如果出现中文乱码问题 需要修改 mimeType 为text/html;charset=utf-8
//加载网页代码
webView.loadData("<h1>title</h1>","text/html","utf-8");
基于一个url加载代码 loadDataWithBaseURL()
不需要考虑中文乱码问题
//加载 以url为基准的数据 比loadData 更加强大
//parameter1 :代码内容中相对地址的基准路径
//parameter2 :网页代码
//parameter3 :数据的内容类型
//parameter4 : 编码
//parameter5 :上一个页面地址
webView.loadDataWithBaseURL("http://www.baidu.com","<html><h1>title</h1>this is content</html>","text/html","utf-8",null);
加载 assets 目录下网页
<html>
<head>
<link type="text/css" rel="stylesheet" href="css/index.css"/>
<script type="text/javascript" src="js/index.js"></script>
</head>
<body>
<table class="table">
<tr>
<td>编号</td>
<td>名称</td>
<td>价格</td>
<td>操作</td>
</tr>
<tr>
<td>0</td>
<td>节操</td>
<td>0</td>
<td onclick="del(this)">删除</td>
</tr>
<tr>
<td>1</td>
<td>贞操</td>
<td>0</td>
<td onclick="del(this)">删除</td>
</tr>
</table>
</body>
</html>
table{
border:double 2px #ccc ;
}
function del(delBt){
var result = confirm("确定删除吗?");
alert("===="+result);
}
/**
* 加载 assets目录下文件
* @return
*/
public String getIndex() {
InputStream is =null;
BufferedReader reader = null;
try {
is = getAssets().open("index.html");
reader = new BufferedReader(new InputStreamReader(is));
StringBuffer sb = new StringBuffer();
while (reader.ready()){
sb.append(reader.readLine().trim());
}
Log.i(TAG, "getIndex: html="+sb.toString());
return sb.toString();
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (is!=null){
is.close();
}
if (reader!=null){
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return "";
}
loadDataWithBaseURL
加载html网页因为使用外部样式 需要使用 loadDataWithBaseUrl() 因为这个可以使用相对基准路径 可以将assets目录作为 基准目录;html 根据基准目录加载响应的css String data = getIndex();
webView.loadDataWithBaseURL("file:///android_asset/",data,"text/html","utf-8",null);
注意点:
路径的格式 :file:///android_asset/
//支持js交互
webView.getSettings().setJavaScriptEnabled(true);
//背景色
webView.setBackgroundColor(Color.GRAY);
; 原始的 网页confirm 确认框
//处理JavaScript confirm 对话框
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(MainActivity.this)
.setTitle("确认提示")
.setMessage(message)
.setNegativeButton("Ok", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNeutralButton("cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
})
.show();
return true;
}
;
对 alert 对话框进行处理 改为 Toast显示
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
//确认交互完成 提交结果 勿忘
result.confirm();
return true;
}
;
重写
WebChromeClient
内部方法
chromeClient = new WebChromeClient(){
//获取 title
@Override
public void onReceivedTitle(WebView view, String title){
tvTitle.setText(title);
}
//获取 icon
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
ImgIcon.setImageBitmap(icon);
}
};
;
在API 23 加入了滚动监听的 get/set方法 ; 在API 23之前需要重写 WebView的
protected void onScrollChanged(final int l, final int t, final int oldl,final int oldt){}
然后再对外提供一个接口
//滚动条监听
webView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
// Log.e(TAG, "onScrollChange: scrollX="+scrollX);
// Log.e(TAG, "onScrollChange: oldScrollX="+oldScrollX);
Log.e(TAG, "onScrollChange: scrollY="+scrollY);
// Log.e(TAG, "onScrollChange: oldScrollY="+oldScrollY);
if (scrollY>0){
floatButton.setVisibility(View.VISIBLE);
}else{
floatButton.setVisibility(View.GONE);
}
dy = scrollX;
}
});
关于滚动条的设置
webView.setHorizontalScrollBarEnabled(false); //水平滚动条不显示
webView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY); //WebView内部显示
回到顶部 实现 使用 方法
scrollTo(x,y);
floatButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.i(TAG, "onClick: dy="+dy);
webView.scrollTo(0,0);
floatButton.setVisibility(View.GONE);
}
});
必须两个都写上, 缺一不可
settings.setUseWideViewPort(true); //支持 viewport
settings.setLoadWithOverviewMode(true); //自适应屏幕
;
;
//保留缩放功能 隐藏缩放控件
settings.setBuiltInZoomControls(true);
settings.setDisplayZoomControls(false);
settings.setSupportZoom(true); //支持缩放
重写
onBackPressed()
通过canGoBack()
判断是否能够回退 ,通过goBack()
实现回退
@Override
public void onBackPressed() {
//判断 WebView 是否可以回退
if (webView.canGoBack()){
webView.goBack();
}else{
Log.e(TAG, "onBackPressed: currentTimeMillis="+System.currentTimeMillis());
Log.e(TAG, "onBackPressed: exit="+exit);
Log.e(TAG, "onBackPressed: currentTimeMillis- exit="+(System.currentTimeMillis()-exit));
if (System.currentTimeMillis()-exit >2000){
Toast.makeText(this, "再按一次退出", Toast.LENGTH_SHORT).show();
exit= System.currentTimeMillis();
}else{
super.onBackPressed();
}
}
}
参考文章: http://www.runoob.com/w3cnote/android-tutorial-webview.html