Android WebView學習

來源:互聯網
上載者:User

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
     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.