每個(gè)項(xiàng)目或簡(jiǎn)單或復(fù)雜的都會(huì)使用到WebView,那么這篇就對(duì)WebView的基本使用做一個(gè)簡(jiǎn)單的介紹。
WebView是什么,能做什么
WebView是android提供的展示網(wǎng)頁(yè)的視圖,基于這個(gè)類你可以在你的app內(nèi)啟動(dòng)網(wǎng)頁(yè)瀏覽器或者只是簡(jiǎn)單的展示在線的內(nèi)容。
WebView是一個(gè)基于webkit引擎、展現(xiàn)web頁(yè)面的控件。Android的WebView在4.4之前是基于WebKit內(nèi)核實(shí)現(xiàn)的,而4.4開(kāi)始基于Chrome內(nèi)核實(shí)現(xiàn)。而Chrome所使用的WebKit內(nèi)核與之前WebView采用的WebKit內(nèi)核是不同的。
1. 首先,要使用WebView,自然創(chuàng)建一個(gè)WebView,創(chuàng)建的方式有兩種:
- 在xml中:
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- 在java代碼中:
WebView view = new WebView(this);
2. 創(chuàng)建WebView,最基本的當(dāng)然是需要展示相關(guān)內(nèi)容,根據(jù)內(nèi)容來(lái)源可以采用不同的方法。
private String content = "<html>" +
"<title>題目沒(méi)想好</title>"+
"<h1>這只是一個(gè)測(cè)試頁(yè)面</h1>" +
"<body>" +
"<p>我開(kāi)始選擇1種生活方式,培養(yǎng)1種思維,考慮承擔(dān)社會(huì)角色中的各種責(zé)任(現(xiàn)在的和未來(lái)的),開(kāi)始養(yǎng)成1,2,3種習(xí)慣,而這其中還需要有很多細(xì)節(jié),這所有的一切來(lái)源于追求。</p>" +
"<p><font color=\"red\"> 任重道遠(yuǎn),至死方休。</font></p>" +
"<p><a href=\"http://www.baidu.com\">眾里尋她千百度</a></p>"+
"</body>" +
"</html>";
/**
* 加載一段html代碼的字符串
* data 內(nèi)容字符串
* mimeType 內(nèi)容的媒體類型
* encoding 編碼類型
*/
wv.loadData(String data,String mimeType,String encoding);//方法原型
wv.loadData(content,"text/html","utf-8");//方法示例(錯(cuò)誤),如果不是英文和數(shù)字會(huì)有亂碼的問(wèn)題,官方文檔說(shuō)除了URL和base64以外,其他的聲明都是按照ascII來(lái)設(shè)置
wv.loadData(content,"text/html;charset=UTF-8",null);//方法示例,以這種方式會(huì)解決亂碼問(wèn)題
/**
* 這個(gè)方法我同樣用來(lái)加載一段html代碼的字符串
*/
wv.loadDataWithBaseURL(String baseUrl,String data,String mimeType,String encoding,String historyUrl);//方法原型
wv.loadDataWithBaseURL(null,content,"text/html","utf-8",null);//方法示例,同樣這種方式也沒(méi)有問(wèn)題
wv.loadUrl(String url);//方法原型
wv.loadUrl("file:///android_asset/***.html");//方法示例,加載項(xiàng)目assets下的html頁(yè)面,html頁(yè)面自己定義,其他部分不變
wv.loadUrl("http://www.baidu.com");//方法示例,加載網(wǎng)頁(yè)
3. WebView將內(nèi)容顯示出來(lái)之后,你可能會(huì)發(fā)現(xiàn)效果跟自己想要的效果有些出入,那么怎么來(lái)對(duì)WebView進(jìn)行一些定制化的設(shè)置呢?這就不得不提到WebSettings類。
WebSettings是用來(lái)管理WebView設(shè)置的抽象類。當(dāng)WebView第一次創(chuàng)建時(shí),相應(yīng)包含一個(gè)WebSettings子類的對(duì)象,此WebSettings對(duì)象中有一套默認(rèn)的設(shè)置,WebSettings對(duì)象的生命周期和其WebView的生命周期綁定,如果WebView對(duì)象被銷毀,再去使用WebSettings的任何方法則會(huì)報(bào)錯(cuò)。
- 看看WebSettings部分相關(guān)的具體使用方法
//獲取WebSettings對(duì)象
WebSettings webSettings = webView.getSettings();
//設(shè)置自適應(yīng)屏幕,兩者合用
webSettings.setUseWideViewPort(true); //將內(nèi)容調(diào)整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小
//設(shè)置滾動(dòng)條
mWebView.setHorizontalScrollBarEnabled(false);//水平滾動(dòng)條不顯示
mWebView.setVerticalScrollBarEnabled(false); //垂直滾動(dòng)條不顯示
//縮放操作
webSettings.setSupportZoom(true); //支持縮放,默認(rèn)為true。可以不顯示設(shè)置,但是如果設(shè)置為false,則下面方法如何設(shè)置都不再支持縮放
webSettings.setBuiltInZoomControls(true); //設(shè)置內(nèi)置的縮放控件。若為false,則該WebView不可縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件,否則放大和縮小過(guò)程中會(huì)出現(xiàn)放大縮小圖標(biāo),雖然放大和縮小動(dòng)作結(jié)束后稍后就會(huì)消失,但是實(shí)在是有些丑
webSettings.setJavaScriptEnabled(true); //如果訪問(wèn)的頁(yè)面中要與Javascript交互,則webview必須設(shè)置支持Javascript
webSettings.setAllowFileAccess(true); //設(shè)置可以訪問(wèn)文件 ,比如當(dāng)網(wǎng)頁(yè)中存在文本文件時(shí)就可以打開(kāi)查看
// 若加載的 html 里有JS 在執(zhí)行動(dòng)畫等操作,會(huì)造成資源浪費(fèi)(CPU、電量)
// 在 onStop 和 onResume 里分別把 setJavaScriptEnabled() 給設(shè)置成 false 和 true 即可
//其他細(xì)節(jié)操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關(guān)閉webview中緩存
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過(guò)JS打開(kāi)新窗口
webSettings.setLoadsImagesAutomatically(true); //支持自動(dòng)加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設(shè)置編碼格式
4. 樣式也調(diào)好了,如果仍然需要對(duì)WebView的內(nèi)部一些鏈接做處理、WebView的加載狀態(tài)甚至是具體的進(jìn)度,這時(shí)候就需要對(duì)WebViewClient類和WebChromeClient類做一些簡(jiǎn)單的了解了。
這兩個(gè)類直接繼承自O(shè)bject。如果WebView只是用來(lái)處理一些html的頁(yè)面內(nèi)容,只用WebViewClient就行了,如果需要更豐富的處理效果,比如Javascript 的對(duì)話框,網(wǎng)站圖標(biāo),網(wǎng)站標(biāo)題,進(jìn)度條處理等,就要用到WebChromeClient。
- WebViewClient代碼示例,主要說(shuō)明處理WebView中的Uri的方法。
//盡管有些方法已經(jīng)廢棄,但是代替它的方法在API級(jí)別較高時(shí)才支持,這樣的話還是選擇用之前的方法
wv.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {// 重寫此方法擊網(wǎng)頁(yè)里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn),不跳到手機(jī)瀏覽器
if(isHttpLink(url)){//同樣可以根據(jù)判斷具體的url類型來(lái)做不同的處理,比如電話號(hào)碼就可以跳轉(zhuǎn)手機(jī)的撥號(hào)頁(yè)面
view.loadUrl(url);
}
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//設(shè)定加載開(kāi)始的動(dòng)作
}
@Override
public void onPageFinished(WebView view, String url) {
//設(shè)定結(jié)束時(shí)的動(dòng)作,比如需要等待webview加載完畢才顯示一些其他的布局或者加載框的消失
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
//出現(xiàn)錯(cuò)誤時(shí),根據(jù)錯(cuò)誤類型展示一個(gè)自定義的h5頁(yè)面或者錯(cuò)誤提示
}
});
//判斷url的類型
private boolean isHttpLink(String url) {
if (url.startsWith("http:") || url.startsWith("https:")) {
return true;
}
return false;
}
- WebChromeClient代碼示例
wv.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress < 100) {
String progress = newProgress + "%";
} else {
}
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
tvTitle.setText(title);
}
/**
*告訴客戶端顯示一個(gè)JavaScript警告對(duì)話框。
* 如果客戶端返回true,則WebView將假定客戶端將處理該對(duì)話框。
* 如果客戶端返回false,它將繼續(xù)執(zhí)行。
*/
@Override
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(WebViewLoadActivity.this)
.setTitle("JsAlert")
.setMessage(message)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setCancelable(false)
.show();
return true;
}
/**
* 告訴客戶端向用戶顯示一個(gè)確認(rèn)對(duì)話框。
* 如果客戶端返回true,WebView將假定客戶端將處理確認(rèn)對(duì)話框并調(diào)用相應(yīng)的JsResult方法。
* 如果客戶端返回false,則默認(rèn)值false將返回到JavaScript。 默認(rèn)行為是返回false。
*/
@Override
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(WebViewLoadActivity.this)
.setTitle("JsConfirm")
.setMessage(message)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
})
.setCancelable(false)
.show();
return true;
}
/**
* 告訴客戶端向用戶顯示一個(gè)提示對(duì)話框。
* 如果客戶端返回true,則WebView將假定客戶端將處理提示對(duì)話框并調(diào)用相應(yīng)的JsPromptResult方法。
* 如果客戶端返回false,則默認(rèn)值false將返回到j(luò)avascript。 默認(rèn)行為是返回false。
*/
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
final EditText et = new EditText(WebViewLoadActivity.this);
et.setText(defaultValue);
new AlertDialog.Builder(WebViewLoadActivity.this)
.setTitle(message)
.setView(et)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.confirm(et.getText().toString());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
result.cancel();
}
})
.setCancelable(false)
.show();
return true;
}
});
5. 銷毀WebView
//銷毀Webview,釋放資源
@Override
protected void onDestroy() {
if (mWebview != null) {
mWebview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
mWebview.clearHistory();
((ViewGroup) mWebview.getParent()).removeView(mWebview);
mWebview.destroy();
mWebview = null;
}
super.onDestroy();
}
WebView的基本使用就先寫到這里,這不是結(jié)束,而是開(kāi)始!
對(duì)于WebView與js的互相調(diào)用,雖然demo也寫了,但是覺(jué)得有不錯(cuò)的博文,思路也很清晰。傳送地址下面已放好。
[參考博文]
http://www.lxweimin.com/p/3c94ae673e2a
http://www.lxweimin.com/p/345f4d8a5cfa