我正在尝试获得一个HybridWebView,JS和C#代码可以在此相互通信。我遵循了the official docs,可以从JS调用C#代码。但是我也需要另一种方法,在所提到的教程中未对此进行介绍。 这就是我走的距离:
在我的HybridWebView控件中,添加了以下几行:
public event EventHandler CallJavascript;
public void InvokeJS()
{
if(CallJavascript != null)
{
CallJavascript(this, EventArgs.Empty);
}
}
在我的自定义渲染器中,我在OnElementChanged()
方法中添加了CallJavascript方法和它
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}"));
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
e.OldElement.CallJavascript += OnElementCallJavascript;
}
if (e.NewElement != null)
{
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
e.NewElement.CallJavascript += OnElementCallJavascript;
}
}
private void OnElementCallJavascript(object sender, EventArgs e)
{
var webView = new Android.Webkit.WebView(_context);
Device.BeginInvokeOnMainThread(() =>
{
webView.EvaluateJavascript("javascript:increaseCount();", null);
});
}
但是,我在OnElementCallJavascript中获取的Webview不是我从中调用方法的WebView,因此不会评估任何javascript。有人知道我如何实现这一目标吗?
答案 0 :(得分:0)
问题是我正在创建一个新的Android.WebKit.WebView
。
像这样使用它可以解决问题:
Device.BeginInvokeOnMainThread(() =>
{
Control.EvaluateJavascript("javascript:increaseCount();", null);
});
答案 1 :(得分:0)
直接/直接使用类似的方法怎么样?
e.NewElement.CallJavascript += (sender, args) =>
{
Control.EvaluateJavascript("javascript:increaseCount();", null);
};
答案 2 :(得分:0)
在Xamarin中的HybridWebView中,表单定义了可绑定的布局和操作:
public class HybridWebView : WebView
{
Action<string> action;
public static BindableProperty EvaluateJavascriptProperty =
BindableProperty.Create(nameof(EvaluateJavascript), typeof(Func<string, Task<string>>), typeof(HybridWebView), null, BindingMode.OneWayToSource);
public Func<string, Task<string>> EvaluateJavascript
{
get { return (Func<string, Task<string>>)GetValue(EvaluateJavascriptProperty); }
set { SetValue(EvaluateJavascriptProperty, value); }
}
public void RegisterAction(Action<string> callback)
{
action = callback;
}
public void Cleanup()
{
action = null;
}
public void InvokeAction(string key)
{
if (action == null)
{
return;
}
action.Invoke(key);
}
}
在页面中调用EvaluateJavacript:
await webview.EvaluateJavascript("javascript:increaseCount();");
在渲染器中:
private HybridWebView xfWebView;
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}"));
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
e.OldElement.CallJavascript += OnElementCallJavascript;
}
if (e.NewElement != null)
{
xfWebView = e.NewElement;
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
if (xfWebView != null)
{
xfWebView.EvaluateJavascript = async (js) =>
{
var reset = new ManualResetEvent(false);
var response = string.Empty;
Device.BeginInvokeOnMainThread(() =>
{
Control?.EvaluateJavascript(js, new JavascriptCallback((r) => { response = r; reset.Set(); }));
});
await Task.Run(() => { reset.WaitOne(); });
return response;
};
}
Control.LoadUrl($"file:///android_asset/Content/{Element.Uri}");
}
}