【发布时间】: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;
【问题讨论】:
-
您可以使用 FormsWebView 作为参考:github.com/SKLn-Rad/Xam.Plugin.Webview
-
是的,谢谢
标签: xamarin xamarin.forms