0

I am having

    <StackLayout.GestureRecognizers >
        <SwipeGestureRecognizer Direction="Left" Swiped="swiped_method"  />
        <SwipeGestureRecognizer Direction="Right" Swiped="swiped_method" />
    </StackLayout.GestureRecognizers>

but when I am swiping sometimes swiped is getting called but sometimes needs to swipe many times.

Mayuri
  • 121
  • 10

1 Answers1

0

I did reproduce the problem on android , but it seems to work fine on iOS.

This is a potential issue just for android, someone also has faced the problem ,pls check https://forums.xamarin.com/discussion/160616 .

I've raised the issue on github : https://github.com/xamarin/Xamarin.Forms/issues/14319

Update

As a workaround we can implement the swipe function in android platform with custom renderer.

Custom renderer
[assembly: ExportRenderer(typeof(StackLayout), typeof(MyRenderer))]
namespace FormsApp.Droid
{
    public class OnSwipeTouchListener : Java.Lang.Object, IOnTouchListener
    {
        private GestureDetector gestureDetector;

        public OnSwipeTouchListener(Context context )
        {
            gestureDetector = new GestureDetector(context, new GestureListener());
        }

        public bool OnTouch(Android.Views.View v, MotionEvent e)
        {
            return gestureDetector.OnTouchEvent(e);
        }

        private class GestureListener : SimpleOnGestureListener {
            private static int SWIPE_THRESHOLD = 100;
            private static int SWIPE_VELOCITY_THRESHOLD = 100;

            public override bool OnDown(MotionEvent e)
            {
                return true;
            }

            public override 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))
                    {
                        if (Math.Abs(diffX) > SWIPE_THRESHOLD && Math.Abs(velocityX) > SWIPE_VELOCITY_THRESHOLD)
                        {
                            if (diffX > 0)
                            {
                                MessagingCenter.Send<object, SwipeDirection>(this, "Hi", SwipeDirection.Right);
                            }
                            else
                            {
                                MessagingCenter.Send<object, SwipeDirection>(this, "Hi", SwipeDirection.Left);
                            }
                            result = true;
                        }
                    }
                    else if (Math.Abs(diffY) > SWIPE_THRESHOLD && Math.Abs(velocityY) > SWIPE_VELOCITY_THRESHOLD)
                    {
                        if (diffY > 0)
                        {
                            MessagingCenter.Send<object, SwipeDirection>(this, "Hi", SwipeDirection.Down);
                        }
                        else
                        {
                            MessagingCenter.Send<object, SwipeDirection>(this, "Hi", SwipeDirection.Up);
                        }
                        result = true;
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine(exception.Message);
                }
                return result;
            }
        }
    }



    public class MyRenderer : VisualElementRenderer<StackLayout>
    {

        Context _context;

        public MyRenderer(Context context) : base(context)
        {
            _context = context;
        }

        protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
        {
            base.OnElementChanged(e);


            StackLayout stackLayout = Element as StackLayout;

            if (stackLayout.GestureRecognizers.Count > 0 && stackLayout.GestureRecognizers[0] is SwipeGestureRecognizer swipe) {
                ViewGroup.SetOnTouchListener(new OnSwipeTouchListener(_context));
                MessagingCenter.Subscribe<object, SwipeDirection>(this, "Hi", (obj, direction) =>
                {
                    swipe.SendSwiped(stackLayout, direction);
                });
            }  
        }
    }
}

Then the Swiped event in Forms project can be triggered every time.

Refer to Android: How to handle right to left swipe gestures.

ColeX
  • 14,062
  • 5
  • 43
  • 240
  • Is there any alternative solution ,I tried some like use box view instead of stack and added InputTransparent="True" but it is not triggering swipe method. – Mayuri Jun 04 '21 at 09:46