Forum Cross Platform with Xamarin
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

How to capture horizontal swipe in a WebView

I created a Xamarin App that utilizes a WebView2 control. the control displays a lot of HTML code.
I am able to scroll vertically, but I would like to add the functionality of PgUp and PgDn based on a swipe left or right
I thought i would be able to catch a Swipe event like this:

SwipeGestureRecognizer swipe = new SwipeGestureRecognizer {Direction = SwipeDirection.Left | SwipeDirection.Right };
swipe.Swiped += OnSwiped;
webView.GestureRecognizers.Add(swipe);

OnSwipe is never called. (Tested in both UWP and Android)
(I am also not getting any errors when this code runs

Am i leaving anything out?
Thanks

Answers

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    In android, you can create a custom renderer for your webwiew. then add SetOnTouchListener for Webview.

    assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyWebviewRender))]
    namespace MyWebviewDemo.Droid
    {
        public class MyWebviewRender : WebViewRenderer
        {
            Context context;
            public MyWebviewRender(Context context) : base(context)
            {
                 this.context = context;
            }
            protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
            {
                base.OnElementChanged(e);
                Control.Settings.JavaScriptEnabled = true;
                Control.Settings.SetAppCacheEnabled(true);
                Control.Settings.CacheMode = Android.Webkit.CacheModes.Normal;
                Control.Settings.SetRenderPriority(RenderPriority.High);
                Control.Settings.DomStorageEnabled = true;
    
                Control.SetOnTouchListener(new MyWebviewTouchListner(context));
            }
        }
    
        internal class MyWebviewTouchListner :Java.Lang.Object, Android.Views.View.IOnTouchListener
        {
            private Context context;
            GestureDetector gestureDetector;
            public MyWebviewTouchListner(Context context)
            {
                this.context = context;
    
                 gestureDetector=    new GestureDetector(context, new GestureListener(this));
            }
    
            public bool OnTouch(Android.Views.View v, MotionEvent e)
            {
             return   gestureDetector.OnTouchEvent(e);
               // throw new NotImplementedException();
            }
        }
    
        internal class GestureListener : Java.Lang.Object, Android.Views.GestureDetector.IOnGestureListener
        {
            private MyWebviewTouchListner myWebviewTouchListner;
    
            public GestureListener(MyWebviewTouchListner myWebviewTouchListner)
            {
                this.myWebviewTouchListner = myWebviewTouchListner;
            }
    
            public bool OnDown(MotionEvent e)
            {
                return false;
            }
    
            public bool OnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
            {
                bool result = false;
                try
                {
                    float diffY = e2.GetY() - e1.GetY();
                    float diffX = e2.GetX() - e1.GetX();
                    if (Math.Abs(diffX) > Math.Abs(diffY))
                    {
                        // You can customize these settings, so 30 is an example
                        if (Math.Abs(diffX) > 30 && Math.Abs(velocityX) > 30)
                        {
                            if (diffX > 0)
                            {
                                //  touchListener.onSwipeRight();
    
                                Toast.MakeText(Android.App.Application.Context, "onSwipeRight", ToastLength.Short).Show();
                            }
                            else
                            {
                                Toast.MakeText(Android.App.Application.Context, "onSwipeLeft", ToastLength.Short).Show();
                                //    touchListener.onSwipeLeft();
                            }
                            result = true;
                        }
                    }
                    else
                    {
                        result = false;
                    }
                }
                catch (Exception exception)
                {
    
                }
                return result;
            }
    
            public void OnLongPress(MotionEvent e)
            {
    
            }
    
            public bool OnScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
            {
                return false;
            }
    
            public void OnShowPress(MotionEvent e)
            {
    
            }
    
            public bool OnSingleTapUp(MotionEvent e)
            {
                return false;
            }
        }
       }
    }
    

    Here is running GIF.

  • biconixbiconix Member ✭✭

    thank you for this reply.
    unfortuantely, i do not understadn how to implement it. I seem to be missing libraries, such as for classes: WebViewRenderer, Control, GestureDetector , Java.Lang.Object, Android.Views.GestureDetector.IOnGestureListener, etc.

  • LeonLuLeonLu Member, Xamarin Team Xamurai

    You do not missing libraries, you should create an custom renderer for your webview like following link. Above code is related to the android platform.
    https://docs.microsoft.com/en-us/xamarin/xamarin-forms/app-fundamentals/custom-renderer/hybridwebview#create-the-custom-renderer-on-android

Sign In or Register to comment.