WebView Renderer with WebViewClient

Hello Everyone,
I am using Web View in my Xamarin PCL application which is working fine. However currently some HTTPS pages stop loading only on Android (iOS working fine). So after some google, I have come up to have custom renderer with custom WebViewClient which handle SSL Error. Now url start loading in Android also perfectly but unfortunately WebView in PCL forms stop firing its Navigating & Navigated events. Also GoBack() stop working on WebView.
Here is my control definition in PCL project
public class CustomWebView : WebView { }

And Here is its Custom Renderer
`public class CustomWebViewRenderer : WebViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
{
base.OnElementChanged(e);

            // Setting the background as transparent
            this.Control.SetBackgroundColor(Android.Graphics.Color.Transparent);
            if (e.OldElement == null)
            {
                Control.SetWebViewClient(new FormsWebViewClient()); 
            }
        }
    }
internal class FormsWebViewClient : Android.Webkit.WebViewClient
    {
        public override void OnReceivedSslError(Android.Webkit.WebView view, SslErrorHandler handler, SslError error)
        {           
            handler.Proceed();
        }
}`

Now if user navigate multiple pages in WebView and then press Backbutton it goes out of WebView (instead going to previous URL page). Previously I was handling back button in PCL Form like this
`public bool CanGoBack()
{
if (webView.CanGoBack)
{
webView.GoBack();
return true;
}
return false;
}

                            protected override bool OnBackButtonPressed()
                            {
                                if(!CanGoBack())
                                    return base.OnBackButtonPressed();
                                return true;
                            }`

But now "CanGoBack" is always false. Also WebView stop firing Navigating & Navigated event in PCL form as I have to do some business checks and also show animation so I had captured these events and it was working fine before renderer.

PCL form XAML look like this:
<web:CustomWebView x:Name="webView" Grid.Row="1" />

And its CodeBehind look like:
`webView.Navigated += (s, e) =>
{
busyIndicator.IsVisible = false;
};
webView.Navigating += (s, e) =>
{
//Some business logic here which is very important
busyIndicator.IsVisible = true;
}

webView.Source = startUrl;`

Please need someone expert opinion. Thank you in advance

Best Answer

  • MuhammadIrfan.9392MuhammadIrfan.9392 USMember ✭✭
    Accepted Answer

    Find out the solution. Sharing it here as it might help some naive Xamarin developer.
    In Custom WebView class (PCL project), have to define own Events
    ` public class CustomWebView : WebView
    {
    public bool CanMoveBack { get; set; }

        public event EventHandler GoBackRequested;       
    
        public event EventHandler<WebNavigatingEventArgs> PageLoadStarted;
        public event EventHandler<WebNavigatedEventArgs> PageLoadEnd;
    
        public void FirePageLoadStarted(WebNavigatingEventArgs e)
        {
            if (PageLoadStarted != null)
                PageLoadStarted(this, e);
        }
    
        public void FirePageLoadEnd(WebNavigatedEventArgs e)
        {
            if (PageLoadEnd != null)
                PageLoadEnd(this, e);
        }
    
        public void FireGoBackRequested()
        {
            if (GoBackRequested != null)
                GoBackRequested(this, EventArgs.Empty);
        }
    }`
    

    And then in Renderer, define custom web view client and handle all events in it
    Control.SetWebViewClient(new FormsWebViewClient(this, customView));

Answers

  • MuhammadIrfan.9392MuhammadIrfan.9392 USMember ✭✭
    Accepted Answer

    Find out the solution. Sharing it here as it might help some naive Xamarin developer.
    In Custom WebView class (PCL project), have to define own Events
    ` public class CustomWebView : WebView
    {
    public bool CanMoveBack { get; set; }

        public event EventHandler GoBackRequested;       
    
        public event EventHandler<WebNavigatingEventArgs> PageLoadStarted;
        public event EventHandler<WebNavigatedEventArgs> PageLoadEnd;
    
        public void FirePageLoadStarted(WebNavigatingEventArgs e)
        {
            if (PageLoadStarted != null)
                PageLoadStarted(this, e);
        }
    
        public void FirePageLoadEnd(WebNavigatedEventArgs e)
        {
            if (PageLoadEnd != null)
                PageLoadEnd(this, e);
        }
    
        public void FireGoBackRequested()
        {
            if (GoBackRequested != null)
                GoBackRequested(this, EventArgs.Empty);
        }
    }`
    

    And then in Renderer, define custom web view client and handle all events in it
    Control.SetWebViewClient(new FormsWebViewClient(this, customView));

Sign In or Register to comment.