Android WebView學習
Android WebView學習
許可權:
在WebView中使用JavaScript
WebView myWebView = (WebView) findViewById(R.id.webview);
WebSettings webSettings = myWebView.getSettings();webSettings.setJavaScriptEnabled(true);
綁定JavaScript代碼到Android源碼
public class JavaScriptInterface {Context mContext;/** Instantiate the interface and set the context */JavaScriptInterface(Context c) { mContext = c; }/** Show a toast from the web page */ public void showToast(String toast) { Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show(); }} WebView webView = (WebView) findViewById(R.id.webview);webView.addJavascriptInterface(new JavaScriptInterface(this), Android);
這段代碼會建立一個名稱為“Android”的JavaScript介面並運行在WebView當中。在這裡,你的Web應用會接入到JavaScriptInterface類。例如,下面為Html何JavaScript代碼,它會在使用者點擊按鈕的時候使用新的介面建立一個Toast訊息。
fragment中webview的曆史操作
webview.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (keyCode == KeyEvent.KEYCODE_BACK && webview.canGoBack()) { //表示按返回鍵 時的操作 webview.goBack(); //後退 return true; //已處理 } } return false; }});webview.loaddata亂碼解決
loadData()中的html data中不能包含'#', '%', '', '?'四中特殊字元,出現這種字元就會出現解析錯誤,顯示找不到網頁還有部分html代碼。需要如何處理呢?我們需要用UrlEncoder編碼為%23, %25, %27, %3f 。
可以使用以下兩種代碼,data為string類型的html代碼
1、webView.loadData(URLEncoder.encode(data, “utf-8”), “text/html”, “utf-8”);這樣一些背景效果什麼的都不怎麼好看了。不推薦。
2、webView.loadDataWithBaseURL(null,data, “text/html”, “utf-8”, null);
這樣就會完美解析了。
編輯
webview中文亂碼解決:
方式一://webView.loadData(htmlData, text/html, UTF-8);//API提供的標準用法,無法解決亂碼問題 webView.loadData(htmlData, text/html; charset=UTF-8, null);//這種寫法可以正確解碼 方式二//先調用這句然後再載入資料webView.getSettings().setDefaultTextEncodingName(UTF-8);//設定預設為utf-8 webView.loadData(htmlData, text/html; charset=UTF-8, null);//這種寫法可以正確解碼 方式三:推薦webView.getSettings().setDefaultTextEncodingName(UTF-8);//設定預設為utf-8 webView.loadDataWithBaseURL(null,data, text/html, utf-8, null);
WebView不載入圖片問題
loadData不能載入圖片內容,如果要載入圖片內容或者獲得更強大的Web支援請使用loadDataWithBaseURL。
android_webview中內容擷取
在程式中經常會用到webView來顯示網頁,但如果能夠得到網頁中的內容呢
//定義java的js互動介面,這個類將會被js操縱。 class WebViewContent{ @JavascriptInterface public void getContent(String data){ webViewContent=data; } }//定義WebView並開啟、綁定與JS的互動,以便擷取webview中的html內容。 WebSettings settings = webView.getSettings(); //開啟縮放支援 settings.setSupportZoom(true); settings.setBuiltInZoomControls(true);//啟用JS settings.setJavaScriptEnabled(true); //預設對縮放比例有限制,導致使用者體驗不好,所以需要設定為使用任意比例縮放。 settings.setUseWideViewPort(true); //使頁面之間可以點選連結導航 webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient()); //初始頁面一般過大,我們設定為75%// webView.setInitialScale(75);//設定預設為utf-8,否則會出現亂碼現象 webView.getSettings().setDefaultTextEncodingName(UTF -8);//使用loadDataWithBaseURL替代loadData以提供更好的體驗和防止亂碼。 webView.loadDataWithBaseURL(null, model.getSummary(), text/html, UTF-8, null); //將JS介面類WebViewContent進行綁定,綁定到js中的handler對象 webView.addJavascriptInterface(new WebViewContent(),handler);//通過WebViewClient操作。 webView.setWebViewClient(new WebViewClient() { @Override public void onPageFinished(WebView view, String url) {// 頁面載入完成擷取內容,通過js代碼即可擷取資料到綁定的js介面對象的對應方法中。 view.loadUrl(javascript:window.handler.getContent(''+document.getElementsByTagName('html')[0].innerHTML+'');); super.onPageFinished(view, url); } });Android 中Webview 自適應螢幕方式一:在HTML頁面中使用Viewport Metadata
上文只是一個只有兩個viewport屬性例子,下文描述了所有支援的viewport屬性及其允許的實值型別。
自動調整尺寸
預定義viewport縮放
viewport的縮放值定義了頁面所允許的縮放範圍。viewport屬性允許您通過以下方式指定您的頁面縮放:
initial-scale
頁面的初始縮放。這個值是一個指示您的頁面相對於螢幕大小倍數的float值。例如,如果您設定初始縮放為“1.0”那麼頁面將根據目標密度1比1的顯示。如果設定為“2.0”那麼頁面將放大2倍。
為了將網頁與viewport尺寸匹配,預設初始縮放是計算過的。因為預設viewport 是800像素寬,如果裝置螢幕判斷為小於800像素寬,初始縮放將以小於1.0的某個值為預設值,以便在螢幕上匹配一個800像素寬的頁面。
minimum-scale
允許的最小縮放。這個值是一個指示您的頁面相對於螢幕大小最小倍數的float值。例如,如果您設定為1.0,那麼因為最小大小和目標密度是1:1的,頁面就不能縮小。
maximum-scale
允許的最大縮放。這個值是一個指示您的頁面相對於螢幕大小最大倍數的float值。例如您設定此值為2.0,那麼您就不能放大超過2倍。
user-scalable
是否允許使用者縮放此頁面。設定為yes允許縮放,no為不允許縮放。預設值是yes。如果您設定此值為no,那麼minimum-scale和maximum-scale將會被忽略,因為縮放不可用。
所以的縮放值必須在0.01到10之間。
這個metadata設定初始縮放為相對於viewport目標密度的原始大小。預定義viewport匹配密度
裝置螢幕的密度基於螢幕決定,由每英寸的像素數(dpi)定義。有三種Android支援的密度:高(hdpi)、中(mdpi)和低(ldpi)
您可以通過使用viewport屬性target-densitydpi來為您的網頁改變目標密度。它允許以下的值:
device-dpi - 使用裝置本地的dpi作為目標dpi。預設縮放將不會起作用。
high-dpi - 使用hdpi作為目標dpi。 中和低密度的螢幕將會適當縮小。.
medium-dpi - 使用mdpi作為目標dpi。 高和低密度的螢幕將會分別放大和縮小。這是預設的密度值。
low-dpi - 使用ldpi作為目標dpi。 中和高密度的螢幕將會適當放大。
- 指定一個dpi值作為目標dpi。該值必須在70-400之間。
例如,您可以通過設定viewport的target-densitydpi屬性,來阻止Android瀏覽器和WebView為不同的解析度縮放網頁。而這個頁面會以當匹配前螢幕的密度的大小顯示。在本例中,您同樣應該定義viewport的寬以匹配裝置寬度,這樣您的頁面才會自然適合螢幕大小。例如:
方式二:用JavaScript適配裝置密度
Android瀏覽器和WebView支援允許您請求當前裝置的螢幕密度的DOM屬性 - DOM屬性 window.devicePixelRatio。這個屬性的值 指定當前裝置使用的比例係數。例如,如果window.devicePixelRatio的值是“1.0”,那麼這個裝置被認為是中等密度並且預設情況下不縮放;如果這個值是“1.5”,那麼這個裝置被認為是高密度並且預設情況下放大1.5x;如果這個值是“0.75”,那麼這個裝置被認為是低密度並且預設情況下縮小0.75x。預設匹配的是中等密度,但是您可以改變這個密度匹配來改變不同螢幕密度下您網頁的縮放。
if (window.devicePixelRatio == 1.5) { alert(This is a high-density screen);} else if (window.devicePixelRatio == 0.75) { alert(This is a low-density screen);}方式三:使用代碼方式
本人測試還是存在問題
關鍵代碼:
settings.setUseWideViewPort(true);
settings.setLoadWithOverviewMode(true);
WebSettings settings = webView.getSettings(); settings.setSupportZoom(true);//開啟縮放支援 settings.setBuiltInZoomControls(true);//開啟縮放支援 settings.setJavaScriptEnabled(true); settings.setDisplayZoomControls(false); //隱藏webview縮放按鈕 //預設對縮放比例有限制,導致使用者體驗不好,所以需要設定為使用任意比例縮放。 settings.setUseWideViewPort(true); //設定webView自適應手機螢幕 settings.setLoadWithOverviewMode(true); settings.setDefaultTextEncodingName(UTF -8);//設定預設為utf-8 //使頁面之間可以點選連結導航 webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient());
參考:http://www.cnblogs.com/bluestorm/archive/2013/04/15/3021996.html
方式四:綜合方式-強烈推薦
參考:http://www.cppblog.com/WhiteDummy/archive/2013/06/25/201300.aspx
如果想要得到正常的倍率,是需要配合網頁端的。(這裡僅討論html5的場合,跨平台嘛)
個人認為,由網頁方面寫死一個寬,再提供一個js的縮放函數(包括圖片,字型),根據不同裝置的解析度來調用,是比較理想的。(當然,也可以用窮舉法,一個解析度進一個網頁,用不同css和不同大小資源 =_=!)
假設寬定位1280,則html5方面必須有:
其中,target-densitydpi是最重要的,它將配合android端的以下代碼使用。
//use html5 viewport attribute settings.setLoadWithOverviewMode(true); settings.setUseWideViewPort(true);
表示我們的代碼支援html5網頁自適應。所謂殺什麼畜生用什麼刀,網頁的事情,dpi適應什麼的,就交給html5去做好了 = =,不用我們在更外面一層蛋疼。
這樣做之後,1280寬的圖片無論在什麼裝置的解析度都是正常的尺寸,不會被做倍數不明的展開,方便我們控制。
最後我採取的策略:
//use html5 viewport attribute settings.setLoadWithOverviewMode(true); settings.setUseWideViewPort(true);
執行個體:自己開發簡易離線瀏覽器
google android sdk離線文檔開啟的時候特別慢,據說是要從Google官網拉取一些東西導致的。離線瀏覽可以解決該問題。PC端可以使用firefox。
但是Android端貌似沒有支援離線工作的瀏覽器。這讓我很傷心。決定開發一個簡易的離線瀏覽器以便在手機端快速查看sdk文檔。
設計到的知識點主要為:WebView的初始化以及縮放問題;將應用程式添加到檔案開啟檔案中。
廢話不多說:以下為代碼部分:
-
MainActivity
-
package net.xby1993.simpleexplorer; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.Window; import android.view.WindowManager; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; public class MainActivity extends Activity { private static final String TAG=MainActivity.class.getSimpleName(); private WebView webView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //設定全屏無標題列 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(R.layout.activity_main); webView = (WebView)findViewById(R.id.webView); WebSettings settings= webView.getSettings(); //開啟縮放支援 settings.setSupportZoom(true); settings.setBuiltInZoomControls(true); settings.setJavaScriptEnabled(true); //預設對縮放比例有限制,導致使用者體驗不好,所以需要設定為使用任意比例縮放。 settings.setUseWideViewPort(true); //設定編碼,防止亂碼 settings.setDefaultTextEncodingName(UTF-8); //使頁面之間可以點選連結導航 webView.setWebViewClient(new WebViewClient()); webView.setWebChromeClient(new WebChromeClient()); //初始頁面一般過大,我們設定為75% webView.setInitialScale(75); Intent intent=getIntent(); //提取檔案管理工具開啟檔案傳送的檔案地址 if(intent.getAction().equals(Intent.ACTION_VIEW)){ String strUri=intent.getDataString(); Log.d(TAG,TAG); Log.d(TAG,strUri); Log.d(TAG,Uri.encode(strUri)); //webView.loadUrl(strUri); 為避免亂碼別使用它 webView.loadDataWithBaseURL(strUri,null, text/html, utf-8, null); } } @Override public boolean onKeyDown(int keyCode,KeyEvent event){ //確保可以通過返回鍵瀏覽曆史頁面棧 if(keyCode==event.KEYCODE_BACK&&webView.canGoBack()){ webView.goBack(); return true; } return super.onKeyDown(keyCode,event); } }
-
AndroidManifest.xml
-