【问题标题】:How to Load Javascript from WebApi In Hybrid Webview Xamarin forms如何在混合 Webview Xamarin 表单中从 WebApi 加载 Javascript
【发布时间】:2019-06-04 10:54:36
【问题描述】:

我正在尝试创建一个混合 webview,它将从 web api 获取其 html 数据,api 返回的数据是字符串形式的。 我现在面临的问题是我无法在我的混合 webview 上绑定或加载 web 的 url,我无法理解必须更改的地方。

这是我到目前为止尝试过但无法使其工作的代码

这里是自定义控件

public class HybridWebView : View
{
    Action<string> action;

    public static readonly BindableProperty UriProperty = BindableProperty.Create(
        propertyName: "Uri",
        returnType: typeof(string),
        declaringType: typeof(HybridWebView),
        defaultValue: default(string));

    public string Uri
    {
        get { return (string)GetValue(UriProperty); }
        set { SetValue(UriProperty, value); }
    }

    public void RegisterAction(Action<string> callback)
    {
        action = callback;
    }

    public void Cleanup()
    {
        action = null;
    }

    public void InvokeAction(string data)
    {
        if (action == null || data == null)
        {
            return;
        }
        action.Invoke(data);
    }
}

这是我的 Android 自定义渲染器

 public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Android.Webkit.WebView>
{
    const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);}";
    Context _context;

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


    protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged(e);

        if (Control == null)
        {
            var webView = new Android.Webkit.WebView(_context);
            webView.Settings.JavaScriptEnabled = true;
            webView.SetWebViewClient(new JavascriptWebViewClient($"javascript: {JavascriptFunction}"));
            webView.Settings.BuiltInZoomControls = true;
            webView.Settings.DisplayZoomControls = false;

            webView.Settings.LoadWithOverviewMode = true;
            webView.Settings.UseWideViewPort = true;
            Control.LoadUrl($"{Element.Uri}");
            SetNativeControl(webView);
        }
        if (e.OldElement != null)
        {
            Control.RemoveJavascriptInterface("jsBridge");
            var hybridWebView = e.OldElement as HybridWebView;
            hybridWebView.Cleanup();
        }
        if (e.NewElement != null)
        {
            Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
            ///Control.LoadUrl($"{Element.Uri}");
        }
    }}

这是我的 IOS 渲染器

public class HybridWebViewRenderer : ViewRenderer<HybridWebView, WKWebView>, IWKScriptMessageHandler
{
    const string JavaScriptFunction = "function invokeCSharpAction(data){window.webkit.messageHandlers.invokeAction.postMessage(data);}";
    WKUserContentController userController;

    protected override void OnElementChanged (ElementChangedEventArgs<HybridWebView> e)
    {
        base.OnElementChanged (e);

        if (Control == null) {
            userController = new WKUserContentController ();
            var script = new WKUserScript (new NSString (JavaScriptFunction), WKUserScriptInjectionTime.AtDocumentEnd, false);
            userController.AddUserScript (script);
            userController.AddScriptMessageHandler (this, "invokeAction");

            var config = new WKWebViewConfiguration { UserContentController = userController };
            var webView = new WKWebView (Frame, config);
            SetNativeControl (webView);
        }
        if (e.OldElement != null) {
            userController.RemoveAllUserScripts ();
            userController.RemoveScriptMessageHandler ("invokeAction");
            var hybridWebView = e.OldElement as HybridWebView;
            hybridWebView.Cleanup ();
        }
        if (e.NewElement != null) {
            string fileName = Path.Combine (NSBundle.MainBundle.BundlePath, string.Format ("Content/{0}", Element.Uri));
            Control.LoadRequest (new NSUrlRequest (new NSUrl (fileName, false)));
        }
    }

    public void DidReceiveScriptMessage (WKUserContentController userContentController, WKScriptMessage message)
    {
        Element.InvokeAction (message.Body.ToString ());
    }
}

这是我拿这个的代码参考 this

这是我在公共库中的 webapi 中为 webview 提供源代码的地方

  var ee = await PolicyService.GetPrivacyPolicy();
        var et = await PolicyService.GetTermsPolicy();

        var htmlprivarcy = new HtmlWebViewSource
        {
            Html = ee
        };

        var htmlforterms = new HtmlWebViewSource
        {
            Html = et
        };
        Privacy.Uri = ee;

【问题讨论】:

标签: xamarin xamarin.forms


【解决方案1】:

混合 webview 将从 web api 获取其 html 数据

你得到的是 HTML 数据,而不是 url,所以

安卓

加载时不要使用Control.LoadUrl($"{Element.Uri}");方法,改为Control.LoadData($"{Element.Uri}","text/html","utf-8");

ios

Control.LoadRequest 更改为Control.LoadHtmlString($"{Element.Uri}", null);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-29
    • 2018-03-03
    • 1970-01-01
    • 2016-04-10
    • 2018-12-29
    • 2022-07-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多