0

I am developing iOS and Android application on Xamarin Forms.

I am using WebView in my project. I want to hide ActivityIndicator on the application when this WebView element is clicked.

The only thing I need is; run a method by clicking on the WebView element.

The codes I've tried;

xamarin.forms Handle Clicked event on WebView (Didn't work)

Calling a C# function through Javascript onClick event in WebView in Xamarin.Forms (Not Working)

XAML

<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <ActivityIndicator x:Name="PageLoader" IsRunning="true" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"></ActivityIndicator>
            <local:Webview21 Navigated="LoadedPage" IsVisible="false" x:Name="MainContent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            </local:Webview21>
</StackLayout>
user3186216
  • 39
  • 1
  • 7

1 Answers1

2

Cause:

Click action will conflict with native JS action.

Solution:

You can use CustomRenderer to add a TapGestureRecognizer and let webview recognize it.Then use MessagingCenter to pass notification when you click the webview.Refer to the following code.

in Forms

using System;
using Xamarin.Forms;
namespace xxx
{
    public class MyWebView:WebView
    {
        public MyWebView()
        {
        }
    }
}

in iOS project

using System;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

using UIKit;
using Foundation;
using ObjCRuntime;

[assembly:ExportRenderer(typeof(MyWebView),typeof(MyWebViewRenderer))]
namespace xxx.iOS
{
    public class MyWebViewRenderer:WebViewRenderer, IUIGestureRecognizerDelegate
    {
        public MyWebViewRenderer()
        {
        }

        protected override void OnElementChanged(VisualElementChangedEventArgs e)
        {
            base.OnElementChanged(e);

            if(NativeView!=null)
            {
                UITapGestureRecognizer tapGestureRecognizer = new UITapGestureRecognizer(this, new Selector("HandleTap:"))
                {
                    WeakDelegate = this,
                    CancelsTouchesInView = false
                };
                NativeView.AddGestureRecognizer(tapGestureRecognizer);
            }

        }

        [Export("gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:")]
        public bool ShouldRecognizeSimultaneously(UIGestureRecognizer gestureRecognizer, UIGestureRecognizer otherGestureRecognizer)
        {
            return true;
        }

        [Export("HandleTap:")]
        void HandleTap(UITapGestureRecognizer tap)
        {
            MessagingCenter.Send<Object>(this,"webviewClicked");
        }

    }
}

in Android Project

using System;
using Android.Content;
using Android.Webkit;

using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

[assembly: ExportRenderer(typeof(MyWebView), typeof(MyWebViewRenderer))]
namespace xxx.Droid
{
    public class MyWebViewRenderer:WebViewRenderer
    {
        public MyWebViewRenderer(Context context):base(context)
        {

        }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);

            if(Control!=null)
            {
                Control.SetWebViewClient(new MyWebviewClient());
                Control.Touch+= (object sender, TouchEventArgs eventArgs) => {


                    if(eventArgs.Event.Action==Android.Views.MotionEventActions.Down)
                    {
                        MessagingCenter.Send<Object>(this, "webviewClicked");
                    }



                };

            }

        }

    }


    internal class MyWebviewClient: WebViewClient
    {
        public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, IWebResourceRequest request)
        {
            return true;
        }
    }



}

Now you can hide the ActivityIndi​​cator when you click the webview

in xxxpage.xaml

<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <ActivityIndicator x:Name="PageLoader" IsRunning="true" HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand"></ActivityIndicator>
            <local:MyWebView Source="xxx"  IsVisible="true" x:Name="MainContent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            </local:MyWebView>
</StackLayout>

in code behind

public partial class xxxPage : ContentPage
    {

        public xxxPage()
        {
            InitializeComponent();

            MessagingCenter.Subscribe<Object>(this, "webviewClicked", (obj) =>
            {

                // you can hide the ActivityIndi​​cator here.

            });

        }

    }
Lucas Zhang
  • 18,630
  • 3
  • 12
  • 22