xamarin.formsxamarin.androidswipe-gesturecustom-rendererpredictive-back

How to disable Predictive Back gesture while swipping left or right in Xamarin Forms Android?


In my Xamarin Forms Android application I'm trying to disable this Predictive back gesture while we swipe left or right from edge of the screen, the app will go back or forward and it messes with the swipe in my tabbed page. sometimes when we swipe to switch tabs it accidentally minimises the application. So I tried the below solution in my Custom ContentPage Renderer, but still it didnt work. Can anyone help me with that ?

I tried all the possibilities below and still issues exists.

[assembly: ExportRenderer(typeof(ContentPage), typeof(CustomPageRenderer))]
namespace ServiceMattersApp.Droid.Renderers
{
    public class CustomPageRenderer : PageRenderer
    {
        public CustomPageRenderer(Context context) : base(context)
        {
        }
        protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
        {
            if (changed && Element != null)
            {
                
                Android.Graphics.Rect exclusionRect = new Android.Graphics.Rect(0, 0,0,0);
                var rects = new Android.Graphics.Rect[] { exclusionRect };
                SystemGestureExclusionRects = rects;
            }

            base.OnLayout(changed, left, top, right, bottom);
        }

    }
}

Here are the other things I tried .

 var rootView = ((Activity)Context).FindViewById(Android.Resource.Id.Content);
                if (rootView != null)
                {
                    ViewCompat.SetSystemGestureExclusionRects(rootView, rects);
                    rootView.RootView.SystemGestureExclusionRects = rects;
                }

I even tried these codes in the OnElementChanged method and still the swipe exists. Expected result - The predictive swipe system gesture should be disabled for left and right side of the screen. Can anyone help me with this please


Solution

  • Firstly, you are passing new Android.Graphics.Rect(0,0,0,0) to the exclusion rects, which is a rectangle with size 0. You instead want to pass new Android.Graphics.Rect(left, top, right, bottom).


    However there's a more fundamental issue. According to the setSystemGestureExclusionRects documentation,

    The system will put a limit of 200dp on the vertical extent of the exclusions it takes into account.

    In other words, the largest your exclusion zone can EVER be is 200dp, or a little over 1 inch, making this API essentially useless.

    As far as I can tell, there are no good workarounds for us. You could hook into the "back" callback, which at least prevents the page from going back, but it doesn't prevent the OS from capturing the swipe and not sending it to your app. This feature is a giant middle finger to those of us with drawing apps, which are now completely broken with no good workaround.


    The best I could do is vertically center the exclusion zone in my control. Here's the code for that:

    protected override void OnLayout(bool changed, int left, int top, int right, int bottom)
    {
        base.OnLayout(changed, left, top, right, bottom);
    
        if (changed && Element != null)
        {
            const int maxHeightDp = 200; // Google restricts exclusion rects to 200dp because reasons
            int maxHeightPx = (int)(maxHeightDp * DeviceDisplay.MainDisplayInfo.Density);
            int controlHeightPx = bottom - top;
            int heightOffsetToVerticallyCenter = Math.Max((controlHeightPx - maxHeightPx) / 2, 0);
            int newTop = top + heightOffsetToVerticallyCenter;
            int newBottom = Math.Min(bottom, newTop + maxHeightPx);
            Android.Graphics.Rect exclusionRect = new Android.Graphics.Rect(left, newTop, right, newBottom);
            SystemGestureExclusionRects = new[] { exclusionRect };
        }
    }