首页 > 解决方案 > Xamarin.Forms 尝试在 JavaScript 和 C# 之间进行通信

问题描述

好的...所以我有一个要添加 Javascript 的自定义 HTMLWebview。我在网上找到的很多示例都有 Android(和 iOS)级别的 HTML,但我更喜欢将 HTML 保留在自定义渲染器中(这样我可以在单独的页面上用自定义内容填充它)。

现在我有一个按钮应该触发一个事件,但它没有发生,我不知道为什么。

这是我的自定义渲染器:

    public class HybridWebView : WebView
    {
        public HybridWebView()
        {
            const string html = @"
        <html>
          <body>
            <h3>Test page</h3>
            <button type=""button"" onClick=""CSharp.ShowToast('Hello from JS')"">Native Interaction</button>
          </body>
        </html>";

            var htmlSource = new HtmlWebViewSource();
           htmlSource.BaseUrl = DependencyService.Get<IBaseUrl>().Get();

            htmlSource.Html = html;
            Source = htmlSource;
        }
    }

这是我的 Android 渲染器:

[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace Test.Droid.Renderers
{
    public class HybridWebViewRenderer : WebViewRenderer
    {

        Context _context;
        public HybridWebViewRenderer(Context context) : base(context)
        {
            _context = context;
        }

        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {

            if (Control != null)
            {
                Control.Settings.JavaScriptEnabled = true;
                Control.AddJavascriptInterface(new HybridJSBridge(Android.App.Application.Context), "CSharp");

            }

            base.OnElementPropertyChanged(sender, e);
        }

    }
}

这是我的桥:

    public class HybridJSBridge : Java.Lang.Object
    {
        Context context;

        public HybridJSBridge(Context context)
        {
            this.context = context;
        }

        [JavascriptInterface]
        [Export]
        public void ShowToast(string msg)
        {
            Toast.MakeText(context, msg, ToastLength.Short).Show();
        }

    }

现在按下按钮时没有任何反应。我希望有人能指出我正确的方向吗?提前致谢!

标签: javascriptc#androidxamarinxamarin.forms

解决方案


你想达到像下面的GIF这样的结果吗?

在此处输入图像描述

我不知道 in 的值是多少BaseUrlhtmlSource.BaseUrl = DependencyService.Get<IBaseUrl>().Get();如果我设置的值return "file:///android_asset";

[assembly: Dependency(typeof(BaseUrl_Android))]
namespace WebviewInvokeJS.Droid
{
    class BaseUrl_Android : IBaseUrl
    {
        public string Get()
        {
            //throw new NotImplementedException();

            return "file:///android_asset";
        }
    }
}

并添加它Control.SetWebViewClient(new WebViewClient());工作HybridWebViewRenderer

[assembly: ExportRenderer(typeof(HybridWebView), typeof(HybridWebViewRenderer))]
namespace WebviewInvokeJS.Droid
{

    public class HybridWebViewRenderer : WebViewRenderer
    {
        Context _context;
        public HybridWebViewRenderer(Context context) : base(context)
        {
            _context = context;
        }
        protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
        {

            if (Control != null)
            {
                Control.Settings.JavaScriptEnabled = true;
                Control.AddJavascriptInterface(new HybridJSBridge(Android.App.Application.Context), "CSharp");
               Control.SetWebViewClient(new WebViewClient());
            }

            base.OnElementPropertyChanged(sender, e);
        }
    }


}

您也可以下载我的演示进行测试。

https://github.com/851265601/XFormsWebviewInvokeJS


推荐阅读