javascript - 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();
}
}
现在按下按钮时没有任何反应。我希望有人能指出我正确的方向吗?提前致谢!
解决方案
你想达到像下面的GIF这样的结果吗?
我不知道 in 的值是多少BaseUrl
,htmlSource.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);
}
}
}
您也可以下载我的演示进行测试。
推荐阅读
- mysql - 我有一个问题 BCRYPT 与 NodeJs 比较比较 Mysql 数据库中的密码
- database - 组件“DEPARTMENT_ID”必须声明为 PLSQL
- php - 如何使用不同的发件人地址从 php laravel 应用程序发送电子邮件
- ansible - 如何使输入与ansible中的问题在同一行?
- php - PHP脚本没有收到我使用Jquery通过AJAX发送给它的文件
- c# - 如何从 ODataPrimitiveSerializer 获取属性信息
- amazon-web-services - 使用 CI/CD 管道将 PHP 应用程序从 Azure DevOps 部署到 AWS
- regex - 正则表达式仅匹配 URL 中的特定参数
- java - 如何使用 elastic-apm-agent 创建的所有详细信息创建自定义跨度?
- docusignapi - 任何用户都可以编辑 DocuSign 信封