帶你溜WebView

鋸齒流沙發表於2017-12-26

在平常的開發中我們一般都會使用到混合開發,比如H5+原生,如果你的app使用到H5開發,那麼webview使用是不可或缺的。所以掌握WebView的知識是多麼重要。 本文要帶你溜WebView,讓你掌握WebView的基本開發,包括與javaSript的互動。 先看下效果圖

彈框.jpg

toast.jpg

這裡首先點選“hello world” 然後javaSript彈出一個alert彈框,接著JavaScript呼叫java的clickText函式,通過回撥,彈出一個toast提示。

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="lwj.com.webview.WebViewActivity">
    <WebView
        android:id="@+id/id_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>
複製程式碼

佈局就一個webview顯示網頁

public class WebViewActivity extends AppCompatActivity {
    private static final String TAG = "WebViewActivity";
    private WebView webView;
    private Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_web_view);
        webView = (WebView) this.findViewById(R.id.id_webview);
        WebSettings webSetting = webView.getSettings();
        webSetting.setDefaultTextEncodingName("utf-8");
        webSetting.setJavaScriptEnabled(true);//支援js
        webSetting.setUseWideViewPort(false);//設定此屬性,可任意縮放比例
        webSetting.setTextZoom(100);//設定字型,相對於正常字型的百分比
        webSetting.setLoadWithOverviewMode(true);
        webSetting.setDomStorageEnabled(true);// 開啟DOM storage
        webView.setWebChromeClient(webChromeClient);
        webView.setWebViewClient(webViewClient);

        String s1 = getHtmlStr("hello world");
        webView.loadData(s1, "text/html", "utf-8");

        //與js互動
        JsToAndroidInterface jsToAndroid = new JsToAndroidInterface();
        jsToAndroid.setOnClickListener(new JsToAndroidInterface.OnTextClickListener() {

            @Override
            public void onTextClick(final String str) {
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(WebViewActivity.this,str,Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        webView.addJavascriptInterface(jsToAndroid, JsToAndroidInterface.INTERFACE_NAME);
    }

    /**
     * html資料
     * @param str
     * @return
     */
    public static String getHtmlStr(String str) {
        StringBuilder builder = null;
        try {
            builder = new StringBuilder();
            builder.append("<html><head>");
            builder.append(" <script language=\"javascript\">function s(){\n" +
                    "alert(\""+str+"!\");\n" +
                    "window.clickOnAndroid.clickText(\""+str+"\");\n" +
                    "}</script>");
            builder.append("</head><body><div class=\"container\"><div class=\"content\">");
            builder.append("<a href=\"javascript:void(0);\" onclick=\"s()\">").append(str).append("</a>");
            builder.append("</div></div></body></html>");
        } catch (Exception e) {
            e.printStackTrace();
        }

        return builder.toString();
    }


    /**
     * 處理各種通知
     * 請求事件相關
     */
    private WebViewClient webViewClient = new WebViewClient() {
        /**
         * 開始載入頁面回撥
         * @param view
         * @param url
         * @param favicon
         */
        @Override
        public void onPageStarted(WebView view, String url, Bitmap favicon) {
            Log.i(TAG, "onPageStarted");
            super.onPageStarted(view, url, favicon);
        }

        /**
         * 攔截url跳轉
         * @param view
         * @param url
         * @return
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            //當前的webview跳轉
            webView.loadUrl(url);
            return true;
        }

        /**
         * 在每一次請求資源時回撥
         * @param view
         * @param request
         * @return
         */
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
            Log.i(TAG, "shouldOverrideUrlLoading");
            return super.shouldOverrideUrlLoading(view, request);
        }

        /**
         * 載入完成回撥
         * @param view
         * @param url
         */
        @Override
        public void onPageFinished(WebView view, String url) {
            Log.i(TAG, "onPageFinished");
            super.onPageFinished(view, url);
        }

        /**
         * 載入錯誤回撥
         * 在這做錯誤處理
         * @param view
         * @param request
         * @param error
         */
        @Override
        public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
            Log.i(TAG, "onReceivedError");
            super.onReceivedError(view, request, error);
        }

        /**
         * https錯誤回撥
         * 可做錯誤處理
         * @param view
         * @param request
         * @param errorResponse
         */
        @Override
        public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
            Log.i(TAG, "onReceivedHttpError");
            super.onReceivedHttpError(view, request, errorResponse);
        }

        /**
         * 載入頁面資源回撥
         * @param view
         * @param url
         */
        @Override
        public void onLoadResource(WebView view, String url) {
            Log.i(TAG, "onLoadResource");
            super.onLoadResource(view, url);
        }
    };
    /**
     * 處理瀏覽器相關的事件
     * 如處理JavaScript的對話方塊
     * 圖示、title、載入進度
     */
    private WebChromeClient webChromeClient = new WebChromeClient() {
        /**
         * javasript 的alert彈框呼叫
         * @param view
         * @param url
         * @param message
         * @param result
         * @return
         */
        @Override
        public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
            Log.i(TAG, "onJsAlert");
            AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
            dlg.setTitle("提示");
            dlg.setMessage(message);
            dlg.setButton(AlertDialog.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.confirm();
                }
            });
            dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface arg0) {
                    result.cancel();
                }
            });
            dlg.show();
            return true;
        }

        /**
         * js的Confirm彈框
         * @param view
         * @param url
         * @param message
         * @param result
         * @return
         */
        @Override
        public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
            AlertDialog dlg = new AlertDialog.Builder(WebViewActivity.this).create();
            dlg.setTitle("提示");
            dlg.setMessage(message);
            dlg.setButton(AlertDialog.BUTTON_POSITIVE, "確定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.confirm();
                }
            });
            dlg.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface arg0, int arg1) {
                    result.cancel();
                }
            });
            dlg.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface arg0) {
                    result.cancel();
                }
            });
            dlg.show();
            return true;
        }

        /**
         * 處理js prompt彈框
         * @param view
         * @param url
         * @param message
         * @param defaultValue
         * @param result
         * @return
         */
        @Override
        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
            Log.i(TAG, "onJsPrompt");
            return super.onJsPrompt(view, url, message, defaultValue, result);
        }

        /**
         * 載入網頁進度條
         * @param view
         * @param newProgress
         */
        @Override
        public void onProgressChanged(WebView view, int newProgress) {
            Log.i(TAG, "onProgressChanged" + newProgress);
            super.onProgressChanged(view, newProgress);
        }

        /**
         * 網頁的title
         * @param view
         * @param title
         */
        @Override
        public void onReceivedTitle(WebView view, String title) {
            Log.i(TAG, "onReceivedTitle" + title);
            super.onReceivedTitle(view, title);
        }
    };

    /**
     * 實現在歷史頁面中 Back
     * 要在當前 Activity
     * 中處理並消費掉該 Back事件:
     */
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) {
            webView.goBack();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
複製程式碼

這裡首先通過WebSettings設定webview支援的型別,包括與JavaScript互動的設定,然後載入html資料,並且設定與JavaScript互動的物件(JsToAndroidInterface),還有關於WebViewClient和WebChromeClient介紹,裡面方法的作用與處理,具體的可以看註釋,最後對webView.goBack()的處理.

public class JsToAndroidInterface {

    public static final String INTERFACE_NAME = "clickOnAndroid";
    private OnTextClickListener mClickListener;

    /**
     * 供js呼叫函式
     * @param str
     */
    @JavascriptInterface
    public void clickText(final String str)
    {
        if(mClickListener != null)
        {
            mClickListener.onTextClick(str);
        }
    }

    /**
     * 回撥介面
     */
    public interface OnTextClickListener
    {
        void onTextClick(String str);
    }

    /**
     * 設定回撥
     * @param listener
     */
    public void setOnClickListener(OnTextClickListener listener)
    {
        mClickListener = listener;
    }
}
複製程式碼

這是與JavaScript互動的物件,JavaScript呼叫clickText,通過回撥給使用者呼叫. 看了本文,應該都瞭解webview的常用知識了吧.

相關文章