【W(wǎng)ebView】WebView的基本使用

每個(gè)項(xiàng)目或簡(jiǎn)單或復(fù)雜的都會(huì)使用到WebView,那么這篇就對(duì)WebView的基本使用做一個(gè)簡(jiǎn)單的介紹。

WebView是什么,能做什么

官方類繼承結(jié)構(gòu).png

WebView是android提供的展示網(wǎng)頁(yè)的視圖,基于這個(gè)類你可以在你的app內(nèi)啟動(dòng)網(wǎng)頁(yè)瀏覽器或者只是簡(jiǎn)單的展示在線的內(nèi)容。
WebView是一個(gè)基于webkit引擎、展現(xiàn)web頁(yè)面的控件。Android的WebView在4.4之前是基于WebKit內(nèi)核實(shí)現(xiàn)的,而4.4開(kāi)始基于Chrome內(nèi)核實(shí)現(xiàn)。而Chrome所使用的WebKit內(nèi)核與之前WebView采用的WebKit內(nèi)核是不同的。

1. 首先,要使用WebView,自然創(chuàng)建一個(gè)WebView,創(chuàng)建的方式有兩種:

  • 在xml中:
<WebView
    android:id="@+id/web_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"/>
  • 在java代碼中:
WebView view = new WebView(this);

2. 創(chuàng)建WebView,最基本的當(dāng)然是需要展示相關(guān)內(nèi)容,根據(jù)內(nèi)容來(lái)源可以采用不同的方法。

private String content = "<html>" +
            "<title>題目沒(méi)想好</title>"+
            "<h1>這只是一個(gè)測(cè)試頁(yè)面</h1>" +
            "<body>" +
            "<p>我開(kāi)始選擇1種生活方式,培養(yǎng)1種思維,考慮承擔(dān)社會(huì)角色中的各種責(zé)任(現(xiàn)在的和未來(lái)的),開(kāi)始養(yǎng)成1,2,3種習(xí)慣,而這其中還需要有很多細(xì)節(jié),這所有的一切來(lái)源于追求。</p>" +
            "<p><font color=\"red\"> 任重道遠(yuǎn),至死方休。</font></p>" +
            "<p><a href=\"http://www.baidu.com\">眾里尋她千百度</a></p>"+
            "</body>" +
            "</html>";

/**
 * 加載一段html代碼的字符串
 * data 內(nèi)容字符串
 * mimeType  內(nèi)容的媒體類型
 * encoding 編碼類型
 */
wv.loadData(String data,String mimeType,String encoding);//方法原型
wv.loadData(content,"text/html","utf-8");//方法示例(錯(cuò)誤),如果不是英文和數(shù)字會(huì)有亂碼的問(wèn)題,官方文檔說(shuō)除了URL和base64以外,其他的聲明都是按照ascII來(lái)設(shè)置
wv.loadData(content,"text/html;charset=UTF-8",null);//方法示例,以這種方式會(huì)解決亂碼問(wèn)題

/**
 * 這個(gè)方法我同樣用來(lái)加載一段html代碼的字符串
 */
wv.loadDataWithBaseURL(String baseUrl,String data,String mimeType,String encoding,String historyUrl);//方法原型
wv.loadDataWithBaseURL(null,content,"text/html","utf-8",null);//方法示例,同樣這種方式也沒(méi)有問(wèn)題

wv.loadUrl(String url);//方法原型
wv.loadUrl("file:///android_asset/***.html");//方法示例,加載項(xiàng)目assets下的html頁(yè)面,html頁(yè)面自己定義,其他部分不變
wv.loadUrl("http://www.baidu.com");//方法示例,加載網(wǎng)頁(yè)

3. WebView將內(nèi)容顯示出來(lái)之后,你可能會(huì)發(fā)現(xiàn)效果跟自己想要的效果有些出入,那么怎么來(lái)對(duì)WebView進(jìn)行一些定制化的設(shè)置呢?這就不得不提到WebSettings類。

WebSettings.png

WebSettings是用來(lái)管理WebView設(shè)置的抽象類。當(dāng)WebView第一次創(chuàng)建時(shí),相應(yīng)包含一個(gè)WebSettings子類的對(duì)象,此WebSettings對(duì)象中有一套默認(rèn)的設(shè)置,WebSettings對(duì)象的生命周期和其WebView的生命周期綁定,如果WebView對(duì)象被銷毀,再去使用WebSettings的任何方法則會(huì)報(bào)錯(cuò)。

  • 看看WebSettings部分相關(guān)的具體使用方法
//獲取WebSettings對(duì)象
WebSettings webSettings = webView.getSettings();

//設(shè)置自適應(yīng)屏幕,兩者合用
webSettings.setUseWideViewPort(true); //將內(nèi)容調(diào)整到適合webview的大小 
webSettings.setLoadWithOverviewMode(true); // 縮放至屏幕的大小

//設(shè)置滾動(dòng)條
mWebView.setHorizontalScrollBarEnabled(false);//水平滾動(dòng)條不顯示
mWebView.setVerticalScrollBarEnabled(false); //垂直滾動(dòng)條不顯示

//縮放操作
webSettings.setSupportZoom(true); //支持縮放,默認(rèn)為true。可以不顯示設(shè)置,但是如果設(shè)置為false,則下面方法如何設(shè)置都不再支持縮放
webSettings.setBuiltInZoomControls(true); //設(shè)置內(nèi)置的縮放控件。若為false,則該WebView不可縮放
webSettings.setDisplayZoomControls(false); //隱藏原生的縮放控件,否則放大和縮小過(guò)程中會(huì)出現(xiàn)放大縮小圖標(biāo),雖然放大和縮小動(dòng)作結(jié)束后稍后就會(huì)消失,但是實(shí)在是有些丑

webSettings.setJavaScriptEnabled(true);  //如果訪問(wèn)的頁(yè)面中要與Javascript交互,則webview必須設(shè)置支持Javascript
webSettings.setAllowFileAccess(true); //設(shè)置可以訪問(wèn)文件 ,比如當(dāng)網(wǎng)頁(yè)中存在文本文件時(shí)就可以打開(kāi)查看

// 若加載的 html 里有JS 在執(zhí)行動(dòng)畫等操作,會(huì)造成資源浪費(fèi)(CPU、電量)
// 在 onStop 和 onResume 里分別把 setJavaScriptEnabled() 給設(shè)置成 false 和 true 即可

//其他細(xì)節(jié)操作
webSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK); //關(guān)閉webview中緩存 
webSettings.setJavaScriptCanOpenWindowsAutomatically(true); //支持通過(guò)JS打開(kāi)新窗口 
webSettings.setLoadsImagesAutomatically(true); //支持自動(dòng)加載圖片
webSettings.setDefaultTextEncodingName("utf-8");//設(shè)置編碼格式

4. 樣式也調(diào)好了,如果仍然需要對(duì)WebView的內(nèi)部一些鏈接做處理、WebView的加載狀態(tài)甚至是具體的進(jìn)度,這時(shí)候就需要對(duì)WebViewClient類和WebChromeClient類做一些簡(jiǎn)單的了解了。

這兩個(gè)類直接繼承自O(shè)bject。如果WebView只是用來(lái)處理一些html的頁(yè)面內(nèi)容,只用WebViewClient就行了,如果需要更豐富的處理效果,比如Javascript 的對(duì)話框,網(wǎng)站圖標(biāo),網(wǎng)站標(biāo)題,進(jìn)度條處理等,就要用到WebChromeClient。

  • WebViewClient代碼示例,主要說(shuō)明處理WebView中的Uri的方法。
//盡管有些方法已經(jīng)廢棄,但是代替它的方法在API級(jí)別較高時(shí)才支持,這樣的話還是選擇用之前的方法
wv.setWebViewClient(new WebViewClient(){ 
      @Override
      public boolean shouldOverrideUrlLoading(WebView view, String url) {// 重寫此方法擊網(wǎng)頁(yè)里面的鏈接還是在當(dāng)前的webview里跳轉(zhuǎn),不跳到手機(jī)瀏覽器
             if(isHttpLink(url)){//同樣可以根據(jù)判斷具體的url類型來(lái)做不同的處理,比如電話號(hào)碼就可以跳轉(zhuǎn)手機(jī)的撥號(hào)頁(yè)面
                   view.loadUrl(url);
             }
             return true;
     }
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            //設(shè)定加載開(kāi)始的動(dòng)作
        }

        @Override
        public void onPageFinished(WebView view, String url) {
            //設(shè)定結(jié)束時(shí)的動(dòng)作,比如需要等待webview加載完畢才顯示一些其他的布局或者加載框的消失
        }

        @Override
        public void onReceivedError(WebView view, int errorCode, String description, String failingUrl)  {
            //出現(xiàn)錯(cuò)誤時(shí),根據(jù)錯(cuò)誤類型展示一個(gè)自定義的h5頁(yè)面或者錯(cuò)誤提示
        }
 });

//判斷url的類型
private boolean isHttpLink(String url) {
        if (url.startsWith("http:") || url.startsWith("https:")) {
            return true;
        }
        return false;
    }
  • WebChromeClient代碼示例
wv.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
                if (newProgress < 100) {
                    String progress = newProgress + "%";
                } else {

                }
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                tvTitle.setText(title);
            }

            /**
             *告訴客戶端顯示一個(gè)JavaScript警告對(duì)話框。
             * 如果客戶端返回true,則WebView將假定客戶端將處理該對(duì)話框。
             * 如果客戶端返回false,它將繼續(xù)執(zhí)行。
             */
            @Override
            public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
                new AlertDialog.Builder(WebViewLoadActivity.this)
                        .setTitle("JsAlert")
                        .setMessage(message)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .setCancelable(false)
                        .show();
                return true;

            }

            /**
             * 告訴客戶端向用戶顯示一個(gè)確認(rèn)對(duì)話框。
             * 如果客戶端返回true,WebView將假定客戶端將處理確認(rèn)對(duì)話框并調(diào)用相應(yīng)的JsResult方法。
             * 如果客戶端返回false,則默認(rèn)值false將返回到JavaScript。 默認(rèn)行為是返回false。
             */
            @Override
            public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
                new AlertDialog.Builder(WebViewLoadActivity.this)
                        .setTitle("JsConfirm")
                        .setMessage(message)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm();
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        })
                        .setCancelable(false)
                        .show();
                return true;
            }

            /**
             * 告訴客戶端向用戶顯示一個(gè)提示對(duì)話框。
             * 如果客戶端返回true,則WebView將假定客戶端將處理提示對(duì)話框并調(diào)用相應(yīng)的JsPromptResult方法。
             * 如果客戶端返回false,則默認(rèn)值false將返回到j(luò)avascript。 默認(rèn)行為是返回false。
             */
            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final JsPromptResult result) {
                final EditText et = new EditText(WebViewLoadActivity.this);
                et.setText(defaultValue);
                new AlertDialog.Builder(WebViewLoadActivity.this)
                        .setTitle(message)
                        .setView(et)
                        .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.confirm(et.getText().toString());
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                result.cancel();
                            }
                        })
                        .setCancelable(false)
                        .show();

                return true;
            }
        });

5. 銷毀WebView

//銷毀Webview,釋放資源
    @Override
    protected void onDestroy() {
        if (mWebview != null) {
            mWebview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebview.clearHistory();
            ((ViewGroup) mWebview.getParent()).removeView(mWebview);
            mWebview.destroy();
            mWebview = null;
        }
        super.onDestroy();
    }

WebView的基本使用就先寫到這里,這不是結(jié)束,而是開(kāi)始!
對(duì)于WebView與js的互相調(diào)用,雖然demo也寫了,但是覺(jué)得有不錯(cuò)的博文,思路也很清晰。傳送地址下面已放好。

[參考博文]
http://www.lxweimin.com/p/3c94ae673e2a
http://www.lxweimin.com/p/345f4d8a5cfa

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容