笔者叨叨叨..
最近状态总是不对,有心无力的晃着美好的时光,明知道自己很菜但是居然不知道从哪里开始让自己成长。前辈告诉我去研究动画,自定义view,那就慢慢来吧,以后会奉上我的学习心得的。
今天就把最近一直在用的WebView总结下吧,感觉还是有很多干货的。不过写下这个名字,自己都感觉惭愧,但是感觉今天又有很多内容要写,感觉好像要囊括webveiw的实用知识了,再来就算是一种激励,希望自己在写的时候遇到问题能查资料解决,比漫无目的地看一些博客来的有意思多了。
这真的是一个高效的学习方法,毕竟自己还是蛮喜欢在键盘上敲打自己的想法。。。
WebView的基本用法:
WebView,我只知道是Android里面的一个控件:一个可以加载网页的控件。他的用法像一般控件一样 : 先写布局文件,再findViewById。区别就是需要很多Web设置,下面是常用的一些设置 :
WebView的常用API
常用方法:
getSettings() //获取设置WebView的WebSettings对象。
setWebViewClient(WebViewClient client) //设置将接收各种通知和请求的WebViewClient。
setWebChromeClient(WebChromeClient client) //设置chrome处理。
WebSettings getSettings() //获取设置WebView的WebSettings对象。
webView.setOnKeyListener(new View.OnKeyListener() { // webview can go back
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
return false;
}
}); //设置网页返回
loadUrl(url); //加载网页
常用的WebSetting API
setAllowFileAccess //启用或禁用WebView访问文件数据
setBlockNetworkImage //是否显示网络图像
setBuiltInZoomControls //设置是否支持缩放
setCacheMode //设置缓冲的模式
setDefaultFontSize //设置默认的字体大小
setDefaultTextEncodingName //设置在解码时时候用的默认编码
setFixedFontFamily //设置固定使用的字体
setJavaScriptEnabled //设置是否支持Javascript
setLayoutAlgorithm //设置布局方式
setLightTouchEnabled //设置用鼠标激活被选项
setSupportZoom //设置是否支持变焦
void setWebViewClient(WebViewClient client) //设置将接收各种通知和请求的WebViewClient。
关于WebSetting里的方法详解博客推荐:
http://blog.csdn.net/a2241076850/article/details/52983939
WebViewClient讲解
WebViewClient就是辅助WebView处理各种通知、请求事件的,具体方法包括:
doUpdateVisitedHistory(WebView view, String url ,boolean isReload)//更新历史记录
onFormResubmission(WebView view, Message dontResend, Message resend)//应用程序重新请求页面数据
onLoadResource(WebView view, String url)//在加载页面资源时会调用,每一个资源(比如图片)的加载都会调用一次
onPageStarted(WebView view, String url, Bitmap favicon)//这个事件就是开始载入页面调用的,通常我们可以在这个设定一个loading的页面,告诉用户程序在等待网络相应。
onPageFinished(WebView view, String url)//在页面加载结束时调用,同样道理,我们知道一个页面载入完成,于是我们可以关闭loading条,切换程序动作。
onReceivedError(WebView view, int errorCode, String description, String failingUrl)//报告错误信息
onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host,Stirng realm)//获取返回信息授权请求
onScaleChanged(WebView view, float oldScale, float newScale)//WebView 发生改变时调用
onUnhandledKeyEvent(WebView view, KeyEvent event)//key事件未被加载时调用
shouldOverrideUrlLoading//并不是每次都在onPageStarted之前开始调用的,就是说一个新的URL不是每次都经过shouldOverrideUrlLoading的,只有在调用webview.loadURL的时候才会调用。
接下来我们来看一下WebViewClient在开发中的应用:
private class webViewClient extends WebViewClient {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//拦截网页跳转
if (url != null && url.contains("/user/setting")) {
Intent intent = new Intent(MainActivity.this, SettingActivity.class);
startActivity(intent);
return true;
//拦截网页拨打电话逻辑,调用本地拨打电话
}else if (url.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
//拦截网页版支付
}else if (url.contains("/payment/pay")){
int currentapiVersion=android.os.Build.VERSION.SDK_INT;
if (currentapiVersion<19) {
String call = "javascript:sumAndOidJava()";
webView.loadUrl(call);
}else {
getPriceEvaluateJavascript(webView);
}
return true;
}else {
//给WebView添加标志位
currentURL = url;
if (currentURL.contains("?")) {
app_url = "&aa=" + appId + "&bb=" + token;
} else {
app_url = "?aa=" + appId + "&bb=" + token;
}
view.loadUrl(currentURL + app_url);
}
return true;
}
//调用Js的getSumAndOid()方法
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void getPriceEvaluateJavascript(WebView webView) {
webView.evaluateJavascript("getSumAndOid()", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
String total=value.replace("\"","");
if (total.contains("*")) {
String price = total.substring(0, total.indexOf("*"));
String orderId = total.substring(total.indexOf("*") + 1, total.length());
pay(orderId, price);
}else {
Toast.makeText(MainActivity.this, "网络不给力,请稍后再试", Toast.LENGTH_SHORT).show();
}
}});
}
//拦截网页里面的控件
@Override
public void onLoadResource(WebView view, String url) {
view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('banner-Bottom')[0].style.display = 'none';}app_setTop();");
view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('detial-serve-content')[0].style.display = 'none';}app_setTop();");
super.onLoadResource(view, url);
}
@Override
public void onReceivedError(WebView view, int errorCode,String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
//这里进行无网络或错误处理,具体可以根据errorCode的值进行判断,做跟详细的处理。
errorUrl = failingUrl;
if (loadingDialog.isShowing()) {
loadingDialog.dismiss();
}
}
@Override
public void onPageFinished(WebView view, String url) {
//在这里拦截网页控件不如onLoadResource效果快好
//view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('banner-Bottom')[0].style.display = 'none';}app_setTop();");
//view.loadUrl("javascript:function app_setTop(){document.getElementsByClassName('detial-serve-content')[0].style.display = 'none';}app_setTop();");
//给网页里面的参数abc和def赋值
view.loadUrl("javascript:function app_setAa(){abc='" + appId + "';}app_setAa();");
view.loadUrl("javascript:function app_setBb(){def='" + token + "';}app_setBb();");
}
}
WebChromeClient解析
WebChromeClient是辅助WebView处理Javascript的对话框,网站图标,网站title,加载进度等 :
onCloseWindow //关闭WebView
onCreateWindow //创建WebView
onJsAlert //处理Javascript中的Alert对话框
onJsConfirm//处理Javascript中的Confirm对话框
onJsPrompt //处理Javascript中的Prompt对话框
onProgressChanged //加载进度条改变
onReceivedlcon //网页图标更改
onReceivedTitle //网页Title更改
onRequestFocus WebView //显示焦点
接下来看看WebChromeClient这个类在实战中的应用:
应用场景:当H5在调用本地相册的时候,没有反应,但是ios,网页,系统浏览器都没有问题就只有android的WebView出来问题,没有办法只有本地处理了:看下面的代码,重写了打开本地文件的openFileChooser方法并做了多方兼容,可以根据开发实际情况选择兼容,最后调用本地的对话框提示用户进行选择拍照还是相册…
private class SelfChromeClient extends WebChromeClient {
// file upload callback (Android 2.2 (API level 8) -- Android 2.3 (API level 10)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback) {
handle(filePathCallback);
}
// file upload callback (Android 3.0 (API level 11) -- Android 4.0 (API level 15)) (hidden method)
public void openFileChooser(ValueCallback filePathCallback, String acceptType) {
handle(filePathCallback);
}
// file upload callback (Android 4.1 (API level 16) -- Android 4.3 (API level 18)) (hidden method)
public void openFileChooser(ValueCallback<Uri> filePathCallback, String acceptType, String capture) {
handle(filePathCallback);
}
// for Lollipop
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, android.webkit.WebChromeClient.FileChooserParams fileChooserParams) {
// Double check that we don't have any existing callbacks
if (mFilePathCallbackArray != null) {
mFilePathCallbackArray.onReceiveValue(null);
}
mFilePathCallbackArray = filePathCallback;
showDialog();
return true;
}
/**
* 处理5.0以下系统回调
*
* @param filePathCallback
*/
private void handle(ValueCallback<Uri> filePathCallback) {
if (mFilePathCallback != null) {
mFilePathCallback.onReceiveValue(null);
}
mFilePathCallback = filePathCallback;
showDialog();
}
/**
* 显示照片选取Dialog
*/
public void showDialog() {
if (ip == null) {
ip = new ImagePick(MainActivity.this);
}
ip.setCancel(new ImagePick.MyDismiss() {
@Override
public void dismiss() {
handleCallback(null);
}
});
ip.show();
}
}
仔细想想貌似就这么多了,可是感觉自己代码一路敲过来,不止这点东西啊,看来是自己没有及时总结,很多解决问题的思路和方法都遗留在时间的长河里,真是可惜,以后又得从头开始百度了…
说于大家——-前车之鉴,后车之师,是为记!