使用自定义渲染器可以禁用CarouselPage
上的iOS
的滑动手势,如下所示:
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;
}
}
}
如何在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
}
}
}
似乎无法以相同的方式访问Subviews
。这样就可以访问Children
Android.Views.View view = (Android.Views.View)GetChildAt(i);
如何知道Child
是哪个ScrollView
?
使用循环来检查这一点,
for (int i = 0; i < ChildCount; ++i)
{
Android.Views.View view = (Android.Views.View)GetChildAt(i);
if (view is ScrollView)
{
}
}
满足以下条件:“ 给定的表达式绝不是提供的(ScrollView
)类型”
所以!如何像在CarouselPage
中那样优雅地禁用iOS
的滑动/滚动?
更新:请参见sample solution。
答案 0 :(得分:1)
几件事。
对于 Android ,您要查找的视图不是ScrollView
,而是ViewPager
。
可以使用 GetChildAt 方法在索引0下找到它。
此外,为什么还要使用VisualElementRenderer<CarouselPage>
作为CustomCarouselPageRenderer
的父类。而是像在iOS上那样使用CarouselPageRenderer
。
最后一件事是在 Android 上,无法禁用ViewPager的滚动。要获得这种行为,您可以收听 Touch 事件。将 TouchEventArgs 的Handled属性设置为 true 可以防止发生滚动。
您的整个课堂看起来像这样:
[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;
}
}
}
只需将 _canScroll 的值更改为true即可进行滚动。
希望这会有所帮助。-
答案 1 :(得分:1)
在Methods
类中覆盖ViewPager
:
public class NonSwipeableViewPager : ViewPager
{
public override bool OnTouchEvent(MotionEvent e)
{
return false;
}
public override bool OnInterceptTouchEvent(MotionEvent ev)
{
return false;
}
public override bool ExecuteKeyEvent(KeyEvent ev)
{
return false;
}
}
更改为CarouselPageRenderer
:
在class
声明中:
public class MyCarouselPageRenderer : VisualElementRenderer<CarouselPage>
{
NonSwipeableViewPager _viewPager;
}
在OnElementChanged
中:
protected override void OnElementChanged(ElementChangedEventArgs<CarouselPage> e)
{
_viewPager = new NonSwipeableViewPager(Context);
}
注意:CarouselPageAdapter
,CarouselPageRenderer
,MeasureSpecFactory
,ObjectJavaBox
和PageContainer
都必须从Xamarin.Forms github复制以启用自定义CarouselPageRenderer
实现。所有这些都在github示例中,但希望这对将来的访问者更清楚地说明了这一点。
注2:我想强调一下,我们试图实现的真实行为最好是使用NavigationPage来完成,因为这使我们可以随时轻松弹出并推送任何页面,而不必解决滑动问题。话虽这么说,希望该解决方案可以帮助需要CarouselPage
上的这种行为的任何人。