android WebView全面總結
來自: http://www.jcodecraeer.com//a/anzhuokaifa/androidkaifa/2013/1010/1569.html
WebView是安卓中用來顯示html文本內容的的控件,對html5也有很好的支持,ios的控件UIWebView差不多。網上對WebView的解釋很多,但都是零星的介紹,導致到現在為止webview給我的印象都是,貌似很強大,其實很雞肋,于是決定總結一下webview的開發經驗。
使用WebView并不需要開通網絡權限
網上有文章說webview需要開通internet權限,否則會出Web page not available錯誤,這是不對的,出現Web page not available并不是因為使用了webview,而是webview訪問了網絡,如果webview只是加載本地html(比如assets目錄中的文件),或者只是加載帶有html文本的字符串,即使沒有internet權限,也不會報錯。
如何調用webview
xml中
<WebView android:id="@+id/blog_detail_webview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:background="#FFFFFF"/>
activity中
mWebView = (WebView)findViewById(R.id.blog_detail_webview); mWebView.getSettings().setJavaScriptEnabled(false); mWebView.getSettings().setSupportZoom(false); mWebView.getSettings().setBuiltInZoomControls(false); mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); mWebView.getSettings().setDefaultFontSize(18);
基本設置
上面的java代碼部分相信大家都懂,可以看到WebView 和其他控件不同的地方在于其屬性設置是調用mWebView.getSettings()來完成的,不知道谷歌這樣設計的用意,其中:
mWebView.getSettings().setJavaScriptEnabled(false);
表示不支持js,如果想讓java和js交互或者本身希望js完成一定的功能請把false改為true。
mWebView.getSettings().setSupportZoom(false);
設置是否支持縮放,我這里為false,默認為true。
mWebView.getSettings().setBuiltInZoomControls(false);
設置是否顯示縮放工具,默認為false。
mWebView.getSettings().setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
一般很少會用到這個,用WebView組件顯示普通網頁時一般會出現橫向滾動條,這樣會導致頁面查看起來非常不方便。LayoutAlgorithm是一個枚舉,用來控制html的布局,總共有三種類型:
NORMAL:正常顯示,沒有渲染變化。
SINGLE_COLUMN:把所有內容放到WebView組件等寬的一列中。
NARROW_COLUMNS:可能的話,使所有列的寬度不超過屏幕寬度。
mWebView.getSettings().setDefaultFontSize(18);
設置默認的字體大小,默認為16,有效值區間在1-72之間。
加載內容
(1)加載assets目錄下的本地網頁
一般我們都是把html文件放在assets目錄下, WebView調用assets目錄下的本地網頁和圖片等資源非常方便,使用形如
mWebView.loadUrl("file:///android_asset/html/test1.html");
的調用方法即可。
(2)加載遠程網頁
mWebView.loadUrl("http://www.google.com");
(3)使用 LoadData 或者 loadDataWithBaseURL方法加載內容
有時候我們的webview可能只是html片段,而不是一個完整的網頁,事實上絕大多數時候都是如此,完整的網頁無需做成應用,而直接在瀏覽器訪問。
這種情況我們使用 LoadData 或者 loadDataWithBaseURL方法,后者用的最多:
void loadDataWithBaseURL (String baseUrl, String data, String mimeType, String encoding, String historyUrl)
loadDataWithBaseURL()比loadData()多兩個參數,可以指定HTML代碼片段中相關資源的相對根路徑,也可以指定歷史Url,其余三個參數相同。
這里主要注意參數baseUrl,baseUrl指定了你的data參數中數據是以什么地址為基準的,因為data中的數據可能會有超鏈接或者是image元素,而很多網站的地址都是用的相對路徑,如果沒有baseUrl,webview將訪問不到這些資源。
舉個例子:
String body ="示例:這里有個img標簽,地址是相對路徑<img src='/uploads/allimg/130923/1FP02V7-0.png' />"; mWebView.loadDataWithBaseURL("http://www.jcodecraeer.com", body, "text/html", "utf-8",null);
如果baseUrl沒有指定為http://www.jcodecraeer.com,那么這張圖片將顯示不出來。
上面的例子其實演示了loadDataWithBaseURL的用法,我們直接加載一個字符串里面的html內容,而有些時候這些內容是從assets目錄下的本地網頁文件中讀取,下面我們將html/test1.html中的內容通過LoadData來加載:
String data = ""; try { // 讀取assets目錄下的文件需要用到AssetManager對象的Open方法打開文件 InputStream is = getAssets().open("html/test2.html"); // loadData()方法需要的是一個字符串數據所以我們需要把文件轉成字符串 ByteArrayBuffer baf = new ByteArrayBuffer(500); int count = 0; while ((count = is.read()) != -1) { baf.append(count); } data = EncodingUtils.getString(baf.toByteArray(), "utf-8"); } catch (IOException e) { e.printStackTrace(); } // 下面兩種方法都可以加載成功 mWebView.loadData(data, "text/html", "utf-8"); // wv.loadDataWithBaseURL("", data, "text/html", "utf-8", "");
這種通過讀取文件再用
loadData
加載其實和mWebView.loadUrl(
"file:///android_asset/html/test1.html"
)是一致的,只不過
loadData
方式因為沒有指定地址的基準url,html/test1.html
文件中一些資源文件或者鏈接地址會失效。
loadDataWithBaseURL和loadData兩個方法加載的HTML代碼片段的不同點在于,loadData()中的html data中不能包含'#', '%', '\', '?'四中特殊字符,在平時測試時,你的數據時,你的數據里含有這些字符,但不會出問題,當出問題時,你可以替換下。
%,會報找不到頁面錯誤,頁面全是亂碼。亂碼樣式見符件。
#,會讓你的goBack失效,但canGoBAck是可以使用的。于是就會產生返回按鈕生效,但不能返回的情況。
WebView內容的處理
android 中webView控件 padding不起作用
在一個布局文件中有一個WebView,想使用padding屬性讓左右向內留出一些空白,但是padding屬性不起左右,內容照樣貼邊顯示,反而移動了右邊滾動條的位置。android的bug,用一個外圍的layout包含webview,可以有所改進,但不能完全解決。其實正確的做法是在webView的加載的css中增加padding,沒必要為了padding而更改xml布局文件。
重寫shouldOverrideUrlLoading時指定url
指定只有url里包含eoe.cn的時候才在webview里打開,否則還是啟動瀏覽器打開.
@Override public boolean shouldOverrideUrlLoading(WebView view, String url) { LogUtil.i(this, "url=" url); if ( url.contains("eoe.cn") == true){ view.loadUrl(url); return true; }else{ Intent in = new Intent (Intent.ACTION_VIEW , Uri.parse(url)); startActivity(in); return true; } }
android:scrollbarStyle控制滾動條位置
WebView有一個設置滾動條位置的屬性:android:scrollbarStyle 可以是insideOverlay可以是outsideOverlay,兩個的區別是SCROLLBARS_INSIDE_OVERLAY的樣式是滾動條在整個page里,類似css中的padding,看代碼下的這個圖吧,很清晰.
mWebView.setScrollBarStyle(View.SCROLLBARS_OUTSIDE_OVERLAY);
mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);