目录
9 WebView案例
9.1 网络访问权限
9.2 WebView创建对象
9.3 访问方式
9.3.1 显示本地assets中的html文件
9.3.2 显示本地html内容
9.3.3 默认浏览器访问URL
9.3.4 调用Android内置浏览器访问URL
9.4 自定义WebViewClient来获取Webview加载各个阶段
9.4.1 设置webview的自定义WebViewClient
9.4.2 shouldOverrideUrlLoading对不同的url进行不同途径打开
9.4.3 onPageStarted开始加载
9.4.4 onPageFinished 结束加载
9.4.5 onReceivedError 接收到返回错误
9.5 重写WebChromeClient
9.5.1 简介
9.5.2 onProgressChanged 获取进度
9.5.3 onReceivedTitle获取网页title
9.5.4 js相关的弹窗要经过处理才能显示;
9.6 显示加载进度
9.7 webview设置缓存
9.8 webview进行缩放
9.9 重写webview的onLongClick()
9.10 设置Webview支持回退
9.12 清理缓存和历史记录
在AndroidManifest.xml中添加
<uses-permission android:name="android.permission.INTERNET" />
第一种:创建WebView对象添加到布局
WebView webView = new WebView(this);
第二种:xml创建
webView.loadUrl("file:///android_asset/test3.html");
webView.getSettings().setDefaultTextEncodingName("utf-8");
String contentStr = "
测试一下webview显示html的content";
// 用loadData()显示的内容不能有中文,中文会显示乱码
// webView.loadData( contentStr, "text/html", "utf-8 ");
// loadDataWithBaseUrl可以显示中文
webView.loadDataWithBaseURL(null, contentStr, "text/html", "utf-8", null);
// 直接调用url,调用手机默认的浏览器
webView.loadUrl("http://www.baidu.com/");
// 直接调用url
webView.loadUrl("http://www.baidu.com/");
//直接创建webViewClient
webView.setWebViewClient(new WebViewClient());
// 直接调用url
webView.loadUrl("http://www.baidu.com/");
// 直接创建WebViewClient
webView.setWebViewClient(new MyWebViewClient());
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// TODO Auto-generated method stub
Log.i(TAG, url + "===");
if (Uri.parse(url).getHost().equals("www.baidu.com")) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}
return false;
}
如果是百度就重新打开手机默认浏览器进行显示,其他的url可以用android手机内置webkit进行浏览
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
// TODO Auto-generated method stub
super.onPageStarted(view, url, favicon);
Log.i(TAG, "onPageStarted:页面开始加载");
}
@Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
Log.i(TAG, "onPageStarted:页面加载结束");
}
@Override
public void onReceivedError(WebView view, int errorCode,
String description, String failingUrl) {
// TODO Auto-generated method stub
super.onReceivedError(view, errorCode, description, failingUrl);
view.loadUrl("file:///android_asset/error.html");
Log.i(TAG, "onReceivedError");
}
注:测试的时候可以手动去断掉手机网络,因为如果连着网络访问一个错误的url,很长时间才能收,有时候还收不到(UC也是这种情况)
WebChromeClient主要辅助Webview处理js、网页title、网站图标、进度条等;
/**
* onProgressChanged 通知应用程序当前网页加载的进度。
*
* 参数说明:
*
* @param view
* 接收WebChromeClient的的webview实例
* @param newProgress
* webview接受的进度
*/
@Override
public void onProgressChanged(WebView view, int newProgress) {
// TODO Auto-generated method stub
super.onProgressChanged(view, newProgress);
if (newProgress <= 100) {
Log.i(TAG, newProgress + "===onProgressChanged===");
}
}
/**
* 当document 的title变化时,会通知应用程序
*
*
* 参数说明:
*
* @param view
* 接收WebViewClient的webview实例
* @param title
* document新的title
*/
@Override
public void onReceivedTitle(WebView view, String title) {
// TODO Auto-generated method stub
super.onReceivedTitle(view, title);
Message message = new Message();
message.what = 100;
message.obj = title;
handler.sendMessage(message);
}
重写:onJsAlert、onJsConfirm、onJsPrompt
我曾经自定义Dialog不知道为什么第一次点击可以,第二次点击就没有反应,如果我ruture false,可以进行不断切换点击,但是会显示父类的dialog
/**
* 覆盖默认的window.alert展示界面,
*/
@Override
public boolean onJsAlert(final WebView view, String url, String message,
JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
view.getContext());
builder.setTitle("对话框").setMessage(message)
.setPositiveButton("确定", null);
builder.setOnKeyListener(new OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.v("onJsAlert", "keyCode==" + keyCode + "event=" + event);
return true;
}
});
// 禁止响应按back键的事件
builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
result.confirm();// 因为没有绑定事件,需要强行confirm,否则页面会变黑显示不了内容。
return true;
// return super.onJsAlert(view, url, message, result);
}
/**
* 覆盖默认的window.confirm展示界面,
*/
@Override
public boolean onJsConfirm(final WebView view, String url, String message,
final JsResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
view.getContext());
builder.setTitle("对话框").setMessage(message)
.setPositiveButton("确定", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
}).setNeutralButton("取消", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
builder.setOnCancelListener(new OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
result.cancel();
}
});
// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.v("onJsConfirm", "keyCode==" + keyCode + "event=" + event);
return true;
}
});
// 禁止响应按back键的事件
// builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
}
/**
* 覆盖默认的window.prompt展示界面,
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message,
String defaultValue, final JsPromptResult result) {
final AlertDialog.Builder builder = new AlertDialog.Builder(
view.getContext());
builder.setTitle("对话框").setMessage(message);
final EditText et = new EditText(view.getContext());
et.setSingleLine();
et.setText(defaultValue);
builder.setView(et).setPositiveButton("确定", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.confirm(et.getText().toString());
}
}).setNeutralButton("取消", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
});
// 屏蔽keycode等于84之类的按键,避免按键后导致对话框消息而页面无法再弹出对话框的问题
builder.setOnKeyListener(new OnKeyListener() {
public boolean onKey(DialogInterface dialog, int keyCode,
KeyEvent event) {
Log.v("onJsPrompt", "keyCode==" + keyCode + "event=" + event);
return true;
}
});
// 禁止响应按back键的事件
// builder.setCancelable(false);
AlertDialog dialog = builder.create();
dialog.show();
return true;
// return super.onJsPrompt(view, url, message, defaultValue,
// result);
}
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
// webview访问url的进度
super.onProgressChanged(view, newProgress);
if (newProgress <= 100) {
Log.i("===webview====progress====", newProgress + "====");
}
}
});
//设置缓存
webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
//不设置缓存
// webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 设置可以支持缩放
webView.getSettings().setSupportZoom(true);
// 设置出现缩放工具
webView.getSettings().setBuiltInZoomControls(true);
//隐藏缩放控件
//webView.getSettings().setDisplayZoomControls(false);
注:并非设置了这两个属性都可以进行缩放,有的网页本身不支持缩放,
www.baidu.com就不支持,换成www.jd.com就可以
因为webview长按会调用系统的复制控件
webView.setOnLongClickListener(new OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
// TODO Auto-generated method stub
return true;
}
});
重写onkeydown()
webview.canGoBack():在webview中含有一个可后退浏览记录时返回true;
webview.goBack():返回webview的上次访问页面
event.getRepeatCount():防止你按着返回键不放,就会重复触发后退事件
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if((keyCode==KeyEvent.KEYCODE_BACK)&&webView.canGoBack()){
//goBack()表示返回WebView的上一页面
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
// 清理cookies
CookieSyncManager.createInstance(this);
CookieSyncManager.getInstance().startSync();
CookieManager.getInstance().removeSessionCookie();
//清理缓存
webView.clearCache(true);
//清理历史记录
webView.clearHistory();