如何创建可点击/可触摸的Xamarin WebView

时间:2019-01-21 22:01:56

标签: xamarin xamarin.ios

我正在Xamarin Forms上开发iOS和Android应用程序。

我在项目中使用WebView。单击此 WebView 元素时,我想在应用程序上隐藏 ActivityIndi​​cator

我唯一需要的是通过单击WebView元素来运行方法。

我尝试过的代码;

xamarin.forms Handle Clicked event on WebView(无效)

Calling a C# function through Javascript onClick event in WebView in Xamarin.Forms(不起作用)

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>

1 个答案:

答案 0 :(得分:2)

原因:

点击操作将与本地JS操作冲突。

解决方案:

您可以使用CustomRenderer添加TapGestureRecognizer并让Webview识别它,然后在单击WebView时使用MessagingCenter传递通知。请参考以下代码。

  

表格

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

在iOS项目中

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");
        }

    }
}
  

在Android项目中

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;
        }
    }



}

现在,您可以在单击网络视图时隐藏ActivityIndi​​cator

  

在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>
  

后面的代码中

public partial class xxxPage : ContentPage
    {

        public xxxPage()
        {
            InitializeComponent();

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

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

            });

        }

    }