[Xamarin] 透過Native Code呼叫 JavaScript function 之 Alert消失問題

2013-10-04

上一次我們在說到 [Xamarin] 透過Native Code呼叫 JavaScript function 在Native中呼叫WebView 中Javascript function ,但是有沒有發現,alert 並沒有任何反應,但是alert 對我來說頗重要,因為很多時候必須要用到這功能來提醒使用者,所以囉查一下,要用特殊的作法,今天就來記錄一下

1.我們先建立一個網頁 很單純 重點是裡面有一個function funcHello() 裡面會alert 一個訊息出來

html code :


<!DOCTYPE html>
 
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title></title>
</head>
<body>
    您好我是測試用的網頁 , 我來自於 <a  href="http://no2don.blogspot.com" target="_top" >當麻許的超技八</a>
    <script>
   1:  
   2:  
   3:         function funcHello() {
   4:             alert('您好我是當麻');
   5:         }
   6:     
</script>
</body>
</html>

為了程式碼簡單,所以我把此檔案佈署在 http://no2don.com/tmp.html 這樣在Android 這邊就直接引用吧

2.在Layout 部分 一個webview 一個按鈕
code:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <WebView
        android:id="@+id/webviewMain"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1" />
    <Button
        android:text="呼叫Javascript Alert"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:id="@+id/btnCallJS" />
</LinearLayout>

預覽:
2013-10-04_160541

3. C# 的部分,下面紅字的部分是新加入的


using System;
 
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Webkit;
using Android.Widget;
using Android.OS;
 
namespace CallSpecialJS
{
    [Activity(Label = "呼叫WebView-Alert", MainLauncher = true, Icon = "@drawable/icon")]
    public class Activity1 : Activity
    {
        WebView webviewMain;
 
 
 
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
 
            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);
 
            webviewMain = FindViewById<WebView>(Resource.Id.webviewMain);
 
            //啟用Javascript Enable
            webviewMain.Settings.JavaScriptEnabled = true;
 
            webviewMain.SetWebViewClient(new CustWebViewClient());
            
            webviewMain.SetWebChromeClient(new CustChromeWebViewClient(this));
            webviewMain.LoadUrl("http://no2don.com/tmp.html");
 
 
            var btnCallJS = FindViewById<Button>(Resource.Id.btnCallJS);
            btnCallJS.Click += delegate
            {
                webviewMain.LoadUrl("javascript:funcHello()");
 
            };
        }
 
 
        private class CustChromeWebViewClient : WebChromeClient
        {
            private Context _context;
 
            public CustChromeWebViewClient(Context father)
            {
                _context = father;
 
            }
 
            public override bool OnJsAlert(WebView view, string url, string message, JsResult result)
            {
                new AlertDialog.Builder(_context).SetTitle("當麻自訂").SetMessage(message).SetPositiveButton("確定", delegate
                {
                    result.Confirm();
                }).Create().Show();
 
 
                return true;
 
            }
        }
 
        /// <summary>
        /// 巢狀Class 繼承WebViewClient
        /// </summary>
        private class CustWebViewClient : WebViewClient
        {
            public override bool ShouldOverrideUrlLoading(WebView view, string url)
            {
                view.LoadUrl(url);
                return true;
            }
 
        }
 
        /// <summary>
        /// 覆寫使其back可以直接回上一頁並非預設的離開APP
        /// </summary>
        /// <param name="keyCode"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        public override bool OnKeyDown(Android.Views.Keycode keyCode, Android.Views.KeyEvent e)
        {
            if (keyCode == Keycode.Back && webviewMain.CanGoBack())
            {
                webviewMain.GoBack();
                return true;
            }
            return base.OnKeyDown(keyCode, e);
        }
    }
}
 

其中,需要特別注意的
a.你首先得建立一個subclass 繼承 WebChromeClient 
b.並且在裡面必須要覆寫調 OnJsAlert method
並且在裡面你可以自訂alert 的各種樣式,所以這時候萬一再webview 中呼叫到alert 會由native這邊作控管。

結果:

Screenshot_2013-10-04-16-13-21

下載:

reference: http://developer.android.com/reference/android/webkit/WebChromeClient.html


當麻許的超技八 2014 | Donma Hsu Design.