Using a custom renderer one can disable the swiping gesture of an CarouselPage
on iOS
like so:
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CustomCarouselPageRenderer))]
namespace App.iOS
{
public class CustomCarouselPageRenderer : CarouselPageRenderer
{
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
UIView view = this.NativeView;
UIScrollView scrollView = (UIKit.UIScrollView)view.Subviews[0];
scrollView.ScrollEnabled = false;
}
}
}
How to accomplish the same on Android?
using Android.Content;
using XamFormsApp.Droid.Renderers;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CustomCarouselPageRenderer))]
namespace StixApp.Droid.Renderers
{
public class CustomCarouselPageRenderer : VisualElementRenderer<CarouselPage>
{
public CustomCarouselPageRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<CarouselPage> e)
{
base.OnElementChanged(e);
var view = this.RootView;
X
X
}
}
}
There appears to be no way to access Subviews
in the same way. One can access Children
like so
Android.Views.View view = (Android.Views.View)GetChildAt(i);
How to know which Child
is ScrollView
if any?
Using a loop to check for this, like so,
for (int i = 0; i < ChildCount; ++i)
{
Android.Views.View view = (Android.Views.View)GetChildAt(i);
if (view is ScrollView)
{
}
}
Yields the following: "The given expression is never of the provided (ScrollView
) type"
So! How to disable CarouselPage
swipe/scrolling as is done in iOS
quite elegantly?
UPDATE: Please see sample solution.
A couple of things.
For Android the view you are looking for is not a ScrollView
but a ViewPager
.
This can be found under the index 0 with the GetChildAt method.
Also, why are you using VisualElementRenderer<CarouselPage>
as the parent class of your CustomCarouselPageRenderer
. Instead use the CarouselPageRenderer
as you did with iOS.
One last thing is that on Android the Scroll of a ViewPager cannot be disabled. To get this behavior you can listen to the Touch event. Setting the Handled property of TouchEventArgs to true will prevent the scrolling from happening.
Your whole class would look something like:
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CustomCarouselPageRenderer))]
namespace StixApp.Droid.Renderers
{
public class CustomCarouselPageRenderer : CarouselPageRenderer
{
private bool _canScroll = false;
public CustomCarouselPageRenderer(Context context) : base(context)
{
}
public CustomCarouselPageRenderer()
{
}
protected override void OnElementChanged(ElementChangedEventArgs<CarouselPage> e)
{
base.OnElementChanged(e);
if (this.ChildCount > 0 && this.GetChildAt(0) is ViewPager viewPager)
{
viewPager.Touch -= ViewPagerTouched;
viewPager.Touch += ViewPagerTouched;
}
}
private void ViewPagerTouched(object sender, TouchEventArgs e)
{
e.Handled = !_canScroll;
}
}
}
Just change the value of _canScroll to true to allow the scrolling.
Hope this helps.-