Android中一個用於網頁顯示的控制項,實際上,也可以看做一個功能最小化的瀏覽器,看起來類似於在微信中打開網頁鏈接的頁面。WebView主要用於在app應用中方便地訪問遠程網頁或本地html資源。同時,WebView也在Android中充當Java代碼和JS代碼之間交互的橋梁。 WebView基本用 ...
Android中一個用於網頁顯示的控制項,實際上,也可以看做一個功能最小化的瀏覽器,看起來類似於在微信中打開網頁鏈接的頁面。WebView主要用於在app應用中方便地訪問遠程網頁或本地html資源。同時,WebView也在Android中充當Java代碼和JS代碼之間交互的橋梁。
WebView基本用法
設置WebView至少有兩種方法
- 佈局文件中添加WebView控制項 & Activity中設置載入頁面
- 調用setContentView()方法,直接通過代碼創建
一般採用第一種方法,在 Activity中設置載入頁面步驟如下
設置載入網址並使用loadUrl()方法載入
對變數private WebView wView;
電腦本地文件:放在app/src/main/assets下的html
wView.loadUrl("file:///android_asset/test.html");
手機本地文件
wView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");
遠程資源:
需先在清單文件 AndroidManifest文件中為app申請網路使用許可權:
<uses-permission android:name="android.permission.INTERNET"/>
填入網頁地址進行載入
wView.loadUrl("https://www.cnblogs.com/ifever/")
載入 HTML 頁面的一小段內容
WView.loadData(String data, String mimeType, String encoding)
- 預設情況下,WebView會調用系統預設瀏覽器載入傳入的網址或者資源。如果需要在當前app頁面內載入,則需要設置WebViewClient 中的shouldOverrideUrlLoading()方法
在當前app頁面內載入
wView.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
return false;
}
以上兩個方法都會在WebView載入新的url時觸發。
Android 5.0以下系統會回調第一個方法,反之回調第二個方法。因此,為了相容不同的系統版本,可以同時重寫這兩個方法。
可以看到,這兩個方法都有一個boolean返回值。假如修改為true,會帶來重定向問題。
返回鍵始終無法退出應用:重定向問題
設置true的代碼如下
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);//手動載入
return true;
}
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
view.loadUrl(request.getUrl().toString());//手動載入
return true;
}
雖然不會影響載入,不過會帶來用戶點擊回退鍵始終無法退出應用的問題,下麵簡單介紹下原理:
假設訪問網頁過程為A - > B - > C共三個站點,在C時點回退,C - > B沒問題,接著再點 B -> A,這個時候問題出現了。儘管B來到了A,但是因為重定向又跳轉到了B,如此迴圈往複...
返回值設為false的情況(且刪去view.loadUrl()方法)就可解決這種問題。其實無論返回true還是false,只要為WebView設置了WebViewClient,都不影響正常的載入功能,只是系統就不會再將url交給第三方的瀏覽器去處理了。
這兩種返回值的真正區別是這樣的:
shouldOverrideUrlLoading返回false,代表將url交給當前WebView載入,也就是正常的載入狀態;shouldOverrideUrlLoading返回true,代表開發者已經對url進行了處理,WebView就不會再對這個url進行載入了。可以用於屏蔽某些網址,藉此實現黑名單機制。
解決了用戶點擊回退鍵始終無法退出應用,但還存在一個顯著問題:用戶希望回退到上一級頁面,卻直接退出了app
回退問題解決方法
goBack() //回退到上一級頁面
canGoBack()//能否回退到上一級頁面
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && wView.canGoBack()) {
//如果按下返回鍵,同時又可以回退到上一級頁面,就返回上一級
wView.goBack();
return true;
}
return super.onKeyDown(keyCode,event);
}
預設情況下,返回鍵會執行finish()方法,結束當前Activity。
有些app為了防止用戶誤觸,在按下返回鍵且無法回退上一級頁面時,會提示需要再次按下返回鍵,才結束當前Activity。這意味著需要在一定時間內連續按動兩次返回鍵才可退出,設計更加人性化。將上述代碼改為
private long exitTime = 0;
@Override
public void onBackPressed() {
if (wView.canGoBack()) {
wView.goBack();
} else {
if ((System.currentTimeMillis() - exitTime) > 2000) {
Toast.makeText(getApplicationContext(), "再按一次退出程式",
Toast.LENGTH_SHORT).show();
exitTime = System.currentTimeMillis();
} else {
finish();
}
}
}
此外修改佈局文件,通過添加按鈕並編寫,也可以添加其他新功能,常用的有
finish(); //關閉當前Activity,一鍵退出
wView.reload(); //刷新當前頁面
wView.setScrollY(0); //滾動到頂部
- 添加進度條
public void onProgressChanged(WebView view, int newProgress){
super.onProgressChanged(view,newProgress);
}
newProgress*100,即可獲得當前載入的百分比,具體方法網上可查,這裡暫不深入
- 標題改為當前網頁標題
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view,title);
setTitle(title);
}
在開通Java許可權後,可以設置網頁彈窗,至少有兩種方式,alert、confirm、prompt三種類型的彈窗
- wView.loadUrl("javascript:alert('hello')");
- wView.evaluateJavascript("javascript:alert('hello')",null);
放置位置如下:
wView.setWebViewClient(new WebViewClient() {
// @Override
// public boolean shouldOverrideUrlLoading(WebView view, String url) {
// return false;
// }
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return false;
}
@Override
public void onPageFinished(WebView view, String url) {
//網頁載入完成時
super.onPageFinished(view, url);
//wView.loadUrl("javascript:alert('hello')");
// wView.evaluateJavascript("javascript:alert('hello')",null);
}});
開通Java許可權及其他設置見下文
WebSettings:WebView狀態管理
WebSettings 用來管理WebView 狀態
為了方便,這裡寫為WebSettings settings = wView.getSettings();
預設情況下,WebView是不支持Javascript的,需要調用 setJavaScriptEnabled(true),即
settings.setJavaScriptEnabled(true);
比如打開百度,添加該行代碼前,網頁少了很多廣告,進入搜索結果會提示需要切換為完整版(因為無法不支持JS所以無法),但不涉及複雜功能的情況下,不影響使用
添加後,反而容易報錯,也存在安全隱患,在本人的oppo r11上調試就會出現net_ERROR錯誤,暫時找不到原因
在網頁自定義縮放
即雙指縮放頁面的手勢控制縮放,由以下代碼實現
settings.setUseWideViewPort(true);//設定支持viewport屬性,有些頁面是很早期的只適配了pc的瀏覽器的頁面,頁面很大,需要寬大的視野來展示,這時候設置為true就可以在足夠的空間拖動,並且頁面可以以任意比例縮放。
settings.setLoadWithOverviewMode(true); //自適應屏幕,用儘可能大的視野展示頁面,一般和上一屬性搭配使用。當然大視野顯示的字都很小。
settings.setBuiltInZoomControls(true); // 使用縮放控制項
settings.setDisplayZoomControls(false); // 隱藏縮放控制項
settings.setSupportZoom(true);//設定支持縮放,只設置此屬性並不能實現縮放,在某些版本的手機上也只是能實現點擊縮放。
在很多網頁依舊不能縮放,經查閱,應該是頁面已經被設置好手機樣式了,但對於傳統的PC版網頁,縮放功能仍有效。
WebView在實際使用中需要用到的兩個類,這裡記錄一下二者的區別
WebViewClient與WebChromeClient的區別
WebViewClient主要幫助WebView處理各種通知、請求事件的
WebChromeClient主要幫助WebView處理Javascript的對話框、網站圖標、網站title、載入進度等
實際使用的話,如果你的WebView只是用來處理一些html的頁面內容,只用WebViewClient就行了,如果需要更豐富的處理效果,比如JS、進度條等,就要用到WebChromeClient,根據實際使用的方法進行回調
參考資料
- 這是一份全面 & 詳細的Webview使用攻略
https://www.jianshu.com/p/3c94ae673e2a/ - Android WebView 的使用(超詳細用法)
https://blog.csdn.net/weixin_40438421/article/details/85700109 - Android WebView全面講解
https://www.2cto.com/kf/201712/706339.html - 安卓使用WebView載入百度首頁
https://www.jianshu.com/p/b073102fb504 - Android webView 支持縮放及自適應屏幕
https://blog.csdn.net/qq_40885379/article/details/83058732 - android WebView(二)縮放
https://blog.csdn.net/w2865673691/article/details/44941495?utm_source=distribute.pc_relevant.none-task - 【天哥】Android開發視頻教程最新版 Android Studio開發
https://www.bilibili.com/video/av38409964 - WebViewClient與WebChromeClient
https://www.cnblogs.com/yaowen/p/5562971.html - WebView(網頁視圖)基本用法|菜鳥教程
https://www.runoob.com/w3cnote/android-tutorial-webview.html