1. 程式人生 > >Android 瀏覽網頁:WebView 嵌入瀏覽器(瀏覽歷史返回、自定義載入失敗介面、支援縮放、獲取標題欄)

Android 瀏覽網頁:WebView 嵌入瀏覽器(瀏覽歷史返回、自定義載入失敗介面、支援縮放、獲取標題欄)

這裡寫圖片描述

一、WebView簡介

  在 Android 手機中內建了一款高效能 webkit 核心瀏覽器,在 SDK 中封裝為一個叫做 WebView 元件.我們可以通過對它的美化和包裝在自己的應用程式裡嵌入一個瀏覽器。

二、WebView在應用中載入網頁的簡單用法

WebView的用法實際上非常簡單,只需要兩步。
1、首先我們在xml佈局中新增WebView。

xml檔案

<WebView 
         android:id="@+id/webview"
          android:layout_width="match_parent"
        android:layout_height
="wrap_content" />

2、通過activity設定WebView在當前應用顯示(setWebViewClient)和載入頁面(loadUrl)

MainActivity

//設定在當前應用中載入網頁,不然手機會使用預設瀏覽器進行開啟
  mwebview.setWebViewClient(new WebViewClient());
  //通過網址載入網頁
        mwebview.loadUrl("http://www.baidu.com");

這樣通過上面兩步的操作,我們開啟應用網頁在聯網的狀態下就會被直接加載出來了。

三、實現WebView的瀏覽網頁歷史回退

  在上面的例項中,我們還需要改進,上面的例項中如果我們通過開始的介面,多次點選瀏覽其他介面,這時我們如果點選back(我們的返回鍵)應用就會自動退出,而不是返回上一個介面。因此,我們需要設定一下返回鍵的返回效果。
在MainActivity中新增如下程式碼。

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {      //如果點選的是返回鍵就進行設定
        if(keyCode==KeyEvent.KEYCODE_BACK){
        //如果瀏覽器介面可以返回就返回,否則關閉activity
if(mwebview.canGoBack()){ mwebview.goBack(); return true; }else{ finish(); return true; } } return super.onKeyDown(keyCode, event); }

效果如開篇圖片所示。

四、自定義載入失敗頁面

  在網路關閉的情況下網頁可能會顯示載入不出來,我們一般不會採用系統給出的載入失敗的介面,一般是自定義。
  自定義載入失敗介面有兩種方式
  1、可以採用FrameLayout佈局,因為幀佈局中新增多個控制元件會像貼小廣告一樣進行覆蓋,這樣我們只需要在WebView控制元件下面新增新的控制元件,監聽頁面的載入錯誤事件,當頁面加載出錯時,使WebView變為“GONE”,該控制元件變為“VISIBLE”
  2、我們也可以不採用幀佈局,直接對WebView和新控制元件的可見屬性進行設定。
 

 <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="頁面載入失敗"
            android:visibility="invisible" />
    </FrameLayout>

五、新增進度條

  這裡添加了進度條,下面的語句是設定進度條風格為水平進度條。
在幀佈局中進度條必須放在WebView下面,不然會被覆蓋掉,不進行顯示。

 <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progressbar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="頁面載入失敗"
            android:visibility="invisible" />
    </FrameLayout>

MainActivity
要實現進度條進度的改變,我們還需要在MainActivity中新增如下語句

        mwebview.getSettings().setJavaScriptEnabled(true);                 mwebview.getSettings().setSupportMultipleWindows(true);
        mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            };

六、實現網頁放大與縮小

  我們在手機上檢視網頁的時候有些網頁採取的是自適應的方式,我們開啟就能看到網頁的完整內容,但是有些網頁不是自適應的,我們必須通過放大或者縮小才能看到完整的網頁。
  其實實現放大與縮小非常簡單隻需要新增一行程式碼。

//支援放縮
mwebview.getSettings().setBuiltInZoomControls(true);

這樣添加了放縮功能之後,在放縮的時候你會發現有放縮的控制按鈕,我們可以通過下面的程式碼隱藏放縮控制按鈕。

mwebview.getSettings().setDisplayZoomControls(false);
即使我們添加了上面的程式碼之後會發現還是會存在一定的問題,對指位置放大後,水平方向不能進行滑動了,我們需要一種能夠支援無限放大的方式。這種方式也非常簡單,我們再來新增一行程式碼。
//支援無限放大縮小
mwebview.getSettings().setUseWideViewPort(true);

注:1、初始縮放值可這樣設定:webView.setInitialScale(initalValue);
  2、縮放後,要使內容適配螢幕,不超出螢幕外顯示,實現換行。這方面效果應該由html控制,而不是webview控制。例如

test

實現自動換行。

七、自定義標題欄

  我們可以看到平時的瀏覽器會有標題欄,我們也來自定義一個標題欄,並實現一定的功能,我這裡製作的標題欄不很好看,大家湊合看啊。
這裡寫圖片描述
佈局中新增標題欄

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button
            android:id="@+id/btn_back"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="返回" />

        <TextView
            android:id="@+id/title"
            android:layout_width="0dip"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_weight="1"
            android:gravity="center"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:text="title" />

        <Button
            android:id="@+id/btn_refesh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="right"
            android:text="重新整理" />
    </LinearLayout>
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent" >

        <WebView
            android:id="@+id/webview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <ProgressBar
            android:id="@+id/progressbar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="invisible" />

        <TextView
            android:id="@+id/erro"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:text="頁面載入失敗"
            android:visibility="invisible" />
    </FrameLayout>

</LinearLayout>

MainActivity中通過onReceivedTitle監聽

   mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            @Override
            public void onReceivedTitle(WebView view, String title) {
                // TODO Auto-generated method stub
                super.onReceivedTitle(view, title);
                mtitle.setText(title);
            }
        });

八、完整點的程式碼:


        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn_network_detail=(Button) findViewById(R.id.bt_network_detail);
        textview_network_detail=(TextView) findViewById(R.id.textview_netDetail);
        btn_back=(Button) findViewById(R.id.btn_back);
        btn_refesh=(Button) findViewById(R.id.btn_refesh);
        textview_erro=(TextView) findViewById(R.id.erro);
        progressbar=(ProgressBar) findViewById(R.id.progressbar);
        mwebview=(WebView) findViewById(R.id.webview);
        mtitle=(TextView) findViewById(R.id.title);

        mwebview.getSettings().setJavaScriptEnabled(true);
        mwebview.getSettings().setSupportMultipleWindows(true);
        mwebview.setWebChromeClient(new WebChromeClient(){
            @Override
            public void onProgressChanged(WebView view, int newProgress) {     
                super.onProgressChanged(view, newProgress);
                progressbar.setProgress(newProgress);

            }
            @Override
            public void onReceivedTitle(WebView view, String title) {
                // TODO Auto-generated method stub
                super.onReceivedTitle(view, title);
                mtitle.setText(title);
            }
        });
     //   mwebview.getSettings().setSupportZoom(true);
        //只設置支援放大時會有問題
        //就是你的內容放大的時候會水平方向會有一部分展示不了
        mwebview.getSettings().setBuiltInZoomControls(true);
        //支援無限放大縮小
        //mwebview.getSettings().setUseWideViewPort(true);
        //去掉放縮按鈕
   mwebview.getSettings().setDisplayZoomControls(false);

        mwebview.setWebViewClient(new WebViewClient(){          
            @Override
            public void onReceivedError(WebView view, int errorCode,
                    String description, String failingUrl) {
                textview_erro.setVisibility(View.VISIBLE);
                textview_erro.setText("網頁載入失敗了啊");
                mwebview.setVisibility(View.GONE);
                super.onReceivedError(view, errorCode, description, failingUrl);
            }
           @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
               progressbar.setVisibility(View.VISIBLE);
            super.onPageStarted(view, url, favicon);
        }

           @Override
        public void onPageFinished(WebView view, String url) {
               progressbar.setVisibility(View.INVISIBLE);
            super.onPageFinished(view, url);
        }

        });
        mwebview.loadUrl("http://www.baidu.com/");
        btn_network_detail.setOnClickListener(this);
        //通過ConnectivityManager物件獲取當前裝置的網路狀態,注意要新增許可權
        connectionManager=(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

九、補充

webview有兩個方法:
webView.setWebChromeClient和webView.setWebViewClient。
WebChromeClient主要處理解析,渲染網頁等瀏覽器做的事情,輔助WebView處理Javascript的對話方塊,網站圖示,網站title,載入進度。
它裡面包括的方法有
  onCloseWindow(關閉WebView)
  onCreateWindow()
  onJsAlert(WebView上alert是彈不出來東西的,需要定製你的WebChromeClient處理彈出)
  onProgressChanged
  onReceivedIcon
  onReceivedTitle
WebViewClient是幫助WebView處理各種通知、請求事件的,具體來說包括:
  onLoadResource (下載地址)
  onPageStart
  onPageFinish
  onReceiveError //自定義錯誤頁面就是用的這個方法
  onReceivedHttpAuthRequest