Forum Xamarin.Forms

How can I detect the click event of any element inside a webview.

Ajay_SBSICAjay_SBSIC USMember ✭✭✭

Hi ,
I have used a webview for displaying HTML content in description field, I have a text in description "go to Home" and on click of that text I want to navigate to another page but i am not able to detect that click on view Model or on code-behind.

I have tried to make it a link and tried to catch the click on webview Navigating and Navigated events but it did not worked , please suggest me any idea, how can I detect the click event of any element inside a webview? any suggestion will be really helpful
Thanks
Ajay

Answers

  • Ajay_SBSICAjay_SBSIC USMember ✭✭✭

    any suggestion??

  • Ajay_SBSICAjay_SBSIC USMember ✭✭✭
    edited November 2018

    I have Implemented this by using callback method from platform specific code.

  • divyagarimelladivyagarimella Member ✭✭✭

    hi anyone have idea please let me know i need it in xamarin forms webview

  • Ajay_SBSICAjay_SBSIC USMember ✭✭✭
    edited December 2019

    @divyagarimella Hi , I have implemented it in this way, please take a look :

    Create Custom Control :

    public class ExtendedWebView : WebView
    {
        public static readonly BindableProperty NavigationUrlProperty = BindableProperty.Create("NavigationUrl", typeof(string), typeof(ExtendedWebView), string.Empty);
    
        public string NavigationUrl
        {
            get { return (string)GetValue(NavigationUrlProperty); }
            set { SetValue(NavigationUrlProperty, value); }
        }
        public event EventHandler LinkClicked;
    
        public void LinkClickedChanged()
        {
            LinkClicked?.Invoke(this, new EventArgs());
        }
    }
    

    Xaml Part :

    <CustomCtrls:ExtendedWebView x:Name="webView" Margin="10,0,5,0" HorizontalOptions="FillAndExpand" LinkClicked="webView_LinkClicked">
                <CustomCtrls:ExtendedWebView.Source>
                    <HtmlWebViewSource Html="{Binding Description}"/>
                </CustomCtrls:ExtendedWebView.Source>
    </CustomCtrls:ExtendedWebView>
    

    **CodeBehind : **

    bool isClicked = false;
    private async void webView_LinkClicked(object sender, EventArgs e)
    {
        if (isClicked) return;
        isClicked = true;
        var inputUrl = sender as ExtendedWebView;
        string navigationModule = inputUrl.NavigationUrl.Split('/').Last();
    
        var AllUsers = App.Container.Resolve<IUserInfoService>().Eject();
    
        var currentPage = App.Container.Resolve<MainViewModel>().OpenTabCommand;
        switch (navigationModule)
        {
            case "First":
                if (!AllUsers.Permissions?.First ?? false)
                    await Application.Current.MainPage.DisplayAlert("", "You do not have permission for this service.", "OK");
                else
                {
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        //Navigation Code goes here
                        (App.Container.Resolve<MainPage>().BindingContext as MainViewModel).OpenTabCommand.Execute(App.Container.Resolve<FirstPage>());
                    });
                }
                break;
            case "Second":
                if (!AllUsers.Permissions?.Second ?? false)
                    Application.Current.MainPage.DisplayAlert("", "You do not have permission for this service.", "OK");
                else
                {
                    //Navigation Code goes here
                    (App.Container.Resolve<MainPage>().BindingContext as MainViewModel).OpenTabCommand.Execute(App.Container.Resolve<SecondPage>());
                }
                break;
            default:
                webView.GoBack();
                break;
        }
        HtmlWebViewSource objhtml = new HtmlWebViewSource();
        objhtml.Html = (this.BindingContext as NewsModel).Description;
        webView.Source = objhtml;
        isClicked = false;
    }
    

    **Android : **

    [assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
    namespace KAPSARC.Droid.Renderers
    {
        public class ExtendedWebViewRenderer : WebViewRenderer
        {
            public ExtendedWebViewRenderer(Context context) : base(context)
            {
    
            }
            static ExtendedWebView _xwebView = null;
            WebView _webView;
    
            class ExtendedWebViewClient : Android.Webkit.WebViewClient
            {
                public override async void OnPageFinished(WebView view, string url)
                {
                    if (_xwebView != null)
                    {
                        int i = 10;
                        while (view.ContentHeight == 0 && i-- > 0) // wait here till content is rendered
                            await System.Threading.Tasks.Task.Delay(100);
                        _xwebView.HeightRequest = view.ContentHeight;
                    }
    
                    var navEvent = Xamarin.Forms.WebNavigationEvent.NewPage;
                    Xamarin.Forms.WebNavigatingEventArgs args = null;
                    string navigationModule = url.Split('/').Last();
                    bool result = Enum.GetNames(typeof(AnnouncementLinkingEnum)).Contains(navigationModule);
                    if (result)
                    {
                        var lastUrl = url.ToString();
                        _xwebView.NavigationUrl = lastUrl;
                        _xwebView.LinkClickedChanged();
                        args = new Xamarin.Forms.WebNavigatingEventArgs(navEvent, new Xamarin.Forms.UrlWebViewSource { Url = lastUrl }, lastUrl);
                    }
                    base.OnPageFinished(view, url);
                }
            }
    
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
                _xwebView = e.NewElement as ExtendedWebView;
                _webView = Control;
    
                if (e.OldElement == null)
                {
                    _webView.SetWebViewClient(new ExtendedWebViewClient());
                }
                var webView = e.NewElement as ExtendedWebView;
            }
    
    
        }
    }
    

    **iOS : **

    [assembly: ExportRenderer(typeof(ExtendedWebView), typeof(ExtendedWebViewRenderer))]
    namespace KAPSARC.iOS.Renderers
    {
        public class ExtendedWebViewRenderer : WebViewRenderer
        {
            static ExtendedWebView wb = new ExtendedWebView();
            protected override void OnElementChanged(VisualElementChangedEventArgs e)
            {
                base.OnElementChanged(e);
                if (e.NewElement as ExtendedWebView == null) return;
                wb = e.NewElement as ExtendedWebView;
    
                Delegate = new ExtendedUIWebViewDelegate(this);
            }
    
            class ExtendedUIWebViewDelegate : UIWebViewDelegate
            {
                public ExtendedWebViewRenderer webViewRenderer;
    
                public ExtendedUIWebViewDelegate(ExtendedWebViewRenderer _webViewRenderer = null)
                {
                    webViewRenderer = _webViewRenderer ?? new ExtendedWebViewRenderer();
                }
    
                public override async void LoadingFinished(UIWebView webView)
                {
                    var wv = webViewRenderer.Element as ExtendedWebView;
                    webView.ScrollView.Bounces = false;
                    if (wv != null)
                    {
                        int i = 50;
                        while (webView.ScrollView.ContentSize.Height == 0 && i-- > 0) // wait here till content is rendered
                            await System.Threading.Tasks.Task.Delay(300);
                        wv.HeightRequest = (double)webView.ScrollView.ContentSize.Height;
                    }
                }
    
                public override bool ShouldStartLoad(UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType)
                {
                    var navEvent = Xamarin.Forms.WebNavigationEvent.NewPage;
                    Xamarin.Forms.WebNavigatingEventArgs args = null;
                    if (navigationType == UIWebViewNavigationType.LinkClicked)
                    {
                        var lastUrl = request.Url.ToString();
                        wb.NavigationUrl = lastUrl;
                        wb.LinkClickedChanged();
                        args = new Xamarin.Forms.WebNavigatingEventArgs(navEvent, new Xamarin.Forms.UrlWebViewSource { Url = lastUrl }, lastUrl);
                        return args == null ? false : args.Cancel;
                    }
                    else
                    {
                        return true;
                    }
    
                }
            }
        }
    }
    

    I have created an Enum named "AnnouncementLinkingEnum" and added all the required Tags or Strings based on which I am navigating to related pages First, second, third and so on.

Sign In or Register to comment.