一蚌父、WebView的設置
//支持獲取手勢焦點漱挚,輸入用戶名竣灌、密碼或其他
webview.requestFocusFromTouch();
WebSettings webSettings = mWebView .getSettings();
webSettings.setJavaScriptEnabled(true); //支持js档玻,如果不設置本行谱姓,html中的js代碼都會失效
webSettings.setPluginsEnabled(true); //支持插件
webSettings.setRenderPriority(RenderPriority.HIGH); //提高渲染的優(yōu)先級
設置自適應屏幕,兩者合用
webSettings.setUseWideViewPort(true); //將圖片調(diào)整到適合webview的大小
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小
webSettings.setSupportZoom(true); //支持縮放浪腐,默認為true纵揍。是下面那個的前提。
webSettings.setBuiltInZoomControls(true); //設置可以縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件
//若上面是false议街,則該WebView不可縮放,這個不管設置什么都不能縮放璧榄。
webSettings.setTextZoom(2);//設置文本的縮放倍數(shù)特漩,默認為 100
webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); //支持內(nèi)容重新布局
webSettings.supportMultipleWindows(); //多窗口
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關閉webview中緩存
webSettings.setAllowFileAccess(true); //設置可以訪問文件
webSettings.setNeedInitialFocus(true); //當webview調(diào)用requestFocus時為webview設置節(jié)點
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過JS打開新窗口,不明白什么意思
webSettings.setLoadsImagesAutomatically(true); //支持自動加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設置編碼格式
webSettings.setStandardFontFamily("");//設置 WebView 的字體骨杂,默認字體為 "sans-serif"
webSettings.setDefaultFontSize(20);//設置 WebView 字體的大小涂身,默認大小為 16
webSettings.setMinimumFontSize(12);//設置 WebView 支持的最小字體大小,默認為 8
以上代碼摘自http://www.reibang.com/p/3fcf8ba18d7f
二搓蚪、webView加載頁面
//webview加載在線網(wǎng)站
mWebView.loadUrl("http://www.baidu.com");
//webview加載assets中的html文件
mWebView.loadUrl("file:///android_asset/test.html");
//webview加載位于sdcard上的html文檔
mWebView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
//webview加載部分html
//data的內(nèi)容必須是符合html規(guī)范的String字符串
mWebView.loadDataWithBaseURL(null,"","text/html","utf-8",null);
mWebView.loadData("","text/html","utf-8");
三蛤售、webView的兩個Client
1.WebViewClient
//如果不添加這一行代碼,那么我們的html會使用系統(tǒng)默認瀏覽器打開
//如果超過一個瀏覽器可選擇,那么會讓用戶自己選擇
mWebView.setWebViewClient(new WebViewClient()
難道一個WebViewClient存在的意義就是讓html在App內(nèi)打開悴能?當然不是揣钦,WebViewClient有很多方法,幫我們處理網(wǎng)頁在加載過程中的各種問題,先來看幾個常用的??:
mWebView.setWebViewClient(new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
//網(wǎng)頁開始加載的時候調(diào)用
super.onPageStarted(view, url, favicon);
Log.d(TAG, "onPageStarted: ");
}
@Override
public void onPageFinished(WebView view, String url) {
//網(wǎng)頁加載結束的時候調(diào)用
super.onPageFinished(view, url);
Log.d(TAG, "onPageFinished: ");
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
//攔截url
Uri url1 = request.getUrl();
Map<String, String> requestHeaders = request.getRequestHeaders();
boolean redirect = request.isRedirect();
Log.d(TAG, "shouldOverrideUrlLoading: ");
return super.shouldOverrideUrlLoading(view, request);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//同上漠酿,只是方法過時了而已
return super.shouldOverrideUrlLoading(view, url);
}
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
Log.d(TAG, "shouldInterceptRequest: request");
return super.shouldInterceptRequest(view, request);
}
@Override
public void onLoadResource(WebView view, String url) {
//網(wǎng)頁中的元素請求資源的時候調(diào)用冯凹,每一次請求都會調(diào)用
super.onLoadResource(view, url);
Log.d(TAG, "onLoadResource: ");
}
});
這樣看什么問題也看不出來,所以我增加了打印日志的代碼炒嘲,下面看日志:由于打印日志太多宇姚,我把日志圖片截成了兩部分,都是比較重要的部分夫凸。
從日志輸出可以看到浑劳,webView在加載一個網(wǎng)頁時所請求的流程:
onPageStarted()--->onLoadResource()--->shouldOverrideUrlLoading--->onPageStarted()--->shouldInterceptRequest--->
onLoadResource--->
shouldInterceptRequest--->
onLoadResource--->...重復
--->onPageFinished--->
shouldInterceptRequest--->
onLoadResource--->...重復
由此可見
1.onPageStarted()會調(diào)用兩遍,而且第一遍并沒有真正請求夭拌,應該只是http建立連接的過程(這個是我猜測的)魔熏,第二次執(zhí)行onPageStarted()才是真正開始加載網(wǎng)頁
2.shouldOverrideUrlLoading在第一次onPageStarted()完成后,會調(diào)用這個方法啼止,用于讓用戶實現(xiàn)攔截url道逗,這是用戶唯一一次攔截url的機會。
3.webview的每一次資源請求前献烦,即調(diào)用onLoadResource()方法前滓窍,都會調(diào)用shouldInterceptRequest()方法來咨詢我們是否需要攔截該請求,或者替換請求數(shù)據(jù)巩那。
為什么onPageFinished()調(diào)用后吏夯,后面還有那么多的請求資源的動作?即横?噪生?還是說因為異步的原因?跪求高手解答
WebViewClient還內(nèi)置了別的很多方法供我們使用
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
//https請求出錯的時候
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
//加載網(wǎng)頁出錯
}
@Override
public void onScaleChanged(WebView view, float oldScale, float newScale) {
super.onScaleChanged(view, oldScale, newScale);
//縮放改變時
}
@Override
public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
super.onUnhandledKeyEvent(view, event);
//未處理鍵盤事件
}
@Override
public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
return super.shouldOverrideKeyEvent(view, event);
//處理鍵盤事件
}
在實際開發(fā)的時候东囚,根據(jù)實際需要重寫必要的方法即可跺嗽,沒有必要全部重寫。
2.WebChromeClient
系統(tǒng)已經(jīng)給我們提供了WebViewClient页藻,那為什么還要一個WebChromeClient呢桨嫁?
沒有比較就沒有傷害,我們來看WebChromeClient中的方法
mWebView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
//處理js中的alert()方法,在alert()之前調(diào)用,return true代表我們自己處理該事件份帐,js中的alert()方法會失效
//message 是彈框中的內(nèi)容
return super.onJsAlert(view,url,message,result);
}
@Override
public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
//處理js中的prompt()方法,在prompt()之前調(diào)用,return true代表我們自己處理該事件璃吧,js中的prompt()方法會失效
//message 是彈框中的內(nèi)容
return super.onJsPrompt(view,url,message,defaultValue,result);
}
@Override
public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
//處理js中的confirm()方法,confirm()之前調(diào)用,return true代表我們自己處理該事件,js中的confirm()方法會失效
//message 是彈框中的內(nèi)容
return super.onJsConfirm(view, url, message, result);
}
@Override
public void onReceivedTitle(WebView view, String title) {
//title就是網(wǎng)頁中title屬性值
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
//newProgress為網(wǎng)頁的加載進度废境,并且這個值并不是有規(guī)律的遞增的畜挨,最大值為100
}
@Override
public void onReceivedIcon(WebView view, Bitmap icon) {
super.onReceivedIcon(view, icon);
//icon是網(wǎng)頁的icon
}
});
由此可見筒繁,WebChromeClient的主要指責是負責webView處理網(wǎng)站title、網(wǎng)站圖標巴元、加載進度以及js的對話框等
需要強調(diào)的是毡咏,在測試中發(fā)現(xiàn),如果不設置WebChromeClient务冕,那么html代碼的中那幾種彈框也無法正常彈出血当,即使你已經(jīng)設置了webSettings.setJavaScriptEnabled(true)也不管用
總結一下
1.要想WebChromeClient中的方法生效,一定記得給webView設置支持js功能禀忆。
2.要想js的彈框可以正常彈出臊旭,在給webview設置支持js功能的前提下,一定要給webView設置WebChromeClient箩退。