Issue
I have my mobile application build using Xamarin forms, which consist of a webView loaded into my application. The WebView Consist of buttons and icons being loaded. I have a requirement to trigger the button event Listener , so that I can do the corresponding functionality. Can anyone help me in how to get the button events being called in Xamarin forms. I have used HybridWebView
as mentioned in the documents and sample ,but nothing seems to be working for me. Below is the code I have used for the same.
code:
HybridWebViewRenderer
using System;
using Android.Content;
using TestProject.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Vinspector.HybridWebView), typeof(HybridWebViewRenderer))]
namespace TestProject.Droid
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavascriptFunction = "function invokeCSharpAction(data){jsBridge.invokeAction(data);};";
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
Console.WriteLine("print inside control is null!!!");
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DatabaseEnabled = true;
webView.Settings.DomStorageEnabled = true;
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
Control.Settings.JavaScriptEnabled = true;
Control.Settings.DatabaseEnabled = true;
Control.Settings.DomStorageEnabled = true;
Control.SetWebViewClient(new JavascriptWebViewClient("javascript:(function getCloseCa(){var btns = document.getElementById('dvCloseBtn');})()"));
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl(“www.google.com”);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
Code For JavascriptWebViewClient
namespace TestProject.Droid
{
public class JavascriptWebViewClient : WebViewClient
{
string _javascript;
public JavascriptWebViewClient(string javascript)
{
_javascript = javascript;
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
base.OnPageFinished(view, url);
if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
view.EvaluateJavascript(_javascript, null);
}
else {
view.LoadUrl(_javascript);
}
}
}
}
Code For JsBridge
namespace TestProject.Droid
{
public class JSBridge : Java.Lang.Object
{
readonly WeakReference<HybridWebViewRenderer> hybridWebViewRenderer;
public JSBridge(HybridWebViewRenderer hybridRenderer)
{
hybridWebViewRenderer = new WeakReference<HybridWebViewRenderer>(hybridRenderer);
}
[JavascriptInterface]
[Export("invokeAction")]
public void InvokeAction(string data)
{
HybridWebViewRenderer hybridRenderer;
if (hybridWebViewRenderer != null && hybridWebViewRenderer.TryGetTarget(out hybridRenderer))
{
((HybridWebView)hybridRenderer.Element).InvokeAction(data);
}
}
}
}
WebPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:TestProject."
x:Class="TestProject..WebPage">
<StackLayout>
<ProgressBar Progress="0.2"
HorizontalOptions="FillAndExpand"
x:Name="progress"
IsVisible="True"/>
<local:HybridWebView
x:Name="hybridWebView"
HeightRequest="1000"
WidthRequest="1000"
Navigating="OnNavigating"
Navigated="OnNavigated"
VerticalOptions="FillAndExpand"
>
</local:HybridWebView>
</StackLayout>
</ContentPage>
WebPage.Xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Vinspector.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Newtonsoft.Json;
using TestProject.Models;
namespace TestProject
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class WebPage : ContentPage
{
public WebPage()
{
InitializeComponent();
hybridWebView.RegisterAction(data => Console.WriteLine("value of data is" + data));
}
protected async override void OnAppearing()
{
base.OnAppearing();
await progress.ProgressTo(0.9, 900, Easing.SpringIn);
}
protected void OnNavigating(object sender, WebNavigatingEventArgs e)
{
progress.IsVisible = true;
Console.WriteLine(" Result OnNavigating....");
}
protected void OnNavigated(object sender, WebNavigatedEventArgs e)
{
progress.IsVisible = false;
Console.WriteLine(" Result OnNavigated....");
var retorno = hybridWebView.EvaluateJavaScriptAsync("common.GetCurrentUserID();");
covertAsync(retorno);
}
private async Task covertAsync(Task<string> retorno)
{
string userID = await retorno;
string AccessToken = LoadApplicationProperty<string>("access_token");
Console.WriteLine(" Result UserID...." + userID + " " + AccessToken);
}
private T LoadApplicationProperty<T>(string key)
{
return (T)Xamarin.Forms.Application.Current.Properties[key];
}
}
}
Solution
You can use the javascript function like the below code to access the buttons and events clicked from webview:
using System;
using Android.Content;
using TestProject.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(Vinspector.HybridWebView), typeof(HybridWebViewRenderer))]
namespace TestProject.Droid
{
public class HybridWebViewRenderer : WebViewRenderer
{
const string JavascriptFunction= "document.getElementById('btnId').onclick= function(data){jsBridge.submissionAction(data);}";`
Context _context;
public HybridWebViewRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<WebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
Console.WriteLine("print inside control is null!!!");
var webView = new Android.Webkit.WebView(_context);
webView.Settings.JavaScriptEnabled = true;
webView.Settings.DatabaseEnabled = true;
webView.Settings.DomStorageEnabled = true;
SetNativeControl(webView);
}
if (e.OldElement != null)
{
Control.RemoveJavascriptInterface("jsBridge");
var hybridWebView = e.OldElement as HybridWebView;
hybridWebView.Cleanup();
}
if (e.NewElement != null)
{
Control.Settings.JavaScriptEnabled = true;
Control.Settings.DatabaseEnabled = true;
Control.Settings.DomStorageEnabled = true;
webView.SetWebViewClient(new `JavascriptWebViewClient(this,string.Format("javascript: {0}", JavascriptFunction)));`
Control.AddJavascriptInterface(new JSBridge(this), "jsBridge");
Control.LoadUrl(“www.google.com”);
}
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
((HybridWebView)Element).Cleanup();
}
base.Dispose(disposing);
}
}
}
Answered By - I'm Coder
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.