Xamarin 表单:CarouselPage 子项的自动滚动
Xamarin forms: Auto scrolling for CarouselPage children
我在 CarouselPage 中有 4 个子项(page1、page2、page3 和 page4),我需要每 3 秒自动滚动一次子项。最初,第 1 页显示在 UI 上,然后第 2 页 -> 第 3 页 -> 第 4 页再次从第 1 页开始。
我使用 OnCurrentPageChanged() 并等待 Task.Delay(TimeSpan.FromSeconds(3));:
protected async override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
await Task.Delay(TimeSpan.FromSeconds(3));
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
}
else if (index == 1)
{
CurrentPage = Children[2];
}
else if (index == 2)
{
CurrentPage = Children[3];
}
else if (index == 3)
{
CurrentPage = Children[0];
}
}
通过这种方式自动滚动成功。
但是如果我在自动滚动之间手动滚动页面,那么时间延迟会减少。突然(不到 3 秒)下一页显示在屏幕上。如果我手动滑动页面,我需要在页面上等待 3 秒。我该如何解决这个问题?
有精彩库CardsView请看
它不仅可以解决您的问题,而且您的应用程序看起来也很酷。
这里是源项目,https://github.com/AndreiMisiukevich/CardView。
检查其中的 CarouselSampleXamlView,SlideShowDuration 属性 用于处理所有内容的轮播。
希望对您有所帮助。
请不要把转页放到OnCurrentPageChanged
方法中
您可以将其放入页面的构造函数中。
public partial class MainPage : CarouselPage
{
bool isStart = true;
public MainPage()
{
InitializeComponent();
Device.StartTimer(new TimeSpan(0, 0, 3), () =>
{
Device.BeginInvokeOnMainThread(() =>
{
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
isStart = true;
}
else if (index == 1)
{
CurrentPage = Children[2];
isStart = true;
}
else if (index == 2)
{
CurrentPage = Children[3];
isStart = true;
}
else if (index == 3)
{
CurrentPage = Children[0];
isStart = true;
}
});
return isStart; // runs again, or false to stop
});
}
}
滑动换页,延迟并没有减少。
但是,如果你想在页面滑动后等待3秒。您必须使用自定义渲染器来实现它。您应该在 android 中监视 viewpager 的 onTouchEvent
(但我在 IOS 中找不到解决方案)。这种方式会卡顿,所以上面的方式会更好
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CustomCarouselPageRenderer))]
namespace CarouselPageDemo.Droid
{
public class CustomCarouselPageRenderer: CarouselPageRenderer
{
public CustomCarouselPageRenderer(Context context) : base(context) {
}
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)
{
MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", "stop");
}
}
}
CarouselPage_CurrentPageChanged
方法
private async void CarouselPage_CurrentPageChanged(object sender, EventArgs e)
{
var tokenSource = new CancellationTokenSource();
await Task.Delay(TimeSpan.FromSeconds(3), tokenSource.Token);
MessagingCenter.Subscribe<App, string>(App.Current, "OpenPage", (snd, arg) =>
{
tokenSource.Cancel();
});
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
}
else if (index == 1)
{
CurrentPage = Children[2];
}
else if (index == 2)
{
CurrentPage = Children[3];
}
else if (index == 3)
{
CurrentPage = Children[0];
}
}
我在 CarouselPage 中有 4 个子项(page1、page2、page3 和 page4),我需要每 3 秒自动滚动一次子项。最初,第 1 页显示在 UI 上,然后第 2 页 -> 第 3 页 -> 第 4 页再次从第 1 页开始。
我使用 OnCurrentPageChanged() 并等待 Task.Delay(TimeSpan.FromSeconds(3));:
protected async override void OnCurrentPageChanged()
{
base.OnCurrentPageChanged();
await Task.Delay(TimeSpan.FromSeconds(3));
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
}
else if (index == 1)
{
CurrentPage = Children[2];
}
else if (index == 2)
{
CurrentPage = Children[3];
}
else if (index == 3)
{
CurrentPage = Children[0];
}
}
通过这种方式自动滚动成功。
但是如果我在自动滚动之间手动滚动页面,那么时间延迟会减少。突然(不到 3 秒)下一页显示在屏幕上。如果我手动滑动页面,我需要在页面上等待 3 秒。我该如何解决这个问题?
有精彩库CardsView请看
它不仅可以解决您的问题,而且您的应用程序看起来也很酷。
这里是源项目,https://github.com/AndreiMisiukevich/CardView。
检查其中的 CarouselSampleXamlView,SlideShowDuration 属性 用于处理所有内容的轮播。
希望对您有所帮助。
请不要把转页放到OnCurrentPageChanged
方法中
您可以将其放入页面的构造函数中。
public partial class MainPage : CarouselPage
{
bool isStart = true;
public MainPage()
{
InitializeComponent();
Device.StartTimer(new TimeSpan(0, 0, 3), () =>
{
Device.BeginInvokeOnMainThread(() =>
{
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
isStart = true;
}
else if (index == 1)
{
CurrentPage = Children[2];
isStart = true;
}
else if (index == 2)
{
CurrentPage = Children[3];
isStart = true;
}
else if (index == 3)
{
CurrentPage = Children[0];
isStart = true;
}
});
return isStart; // runs again, or false to stop
});
}
}
滑动换页,延迟并没有减少。
但是,如果你想在页面滑动后等待3秒。您必须使用自定义渲染器来实现它。您应该在 android 中监视 viewpager 的 onTouchEvent
(但我在 IOS 中找不到解决方案)。这种方式会卡顿,所以上面的方式会更好
[assembly: ExportRenderer(typeof(CarouselPage), typeof(CustomCarouselPageRenderer))]
namespace CarouselPageDemo.Droid
{
public class CustomCarouselPageRenderer: CarouselPageRenderer
{
public CustomCarouselPageRenderer(Context context) : base(context) {
}
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)
{
MessagingCenter.Send<App, string>(App.Current as App, "OpenPage", "stop");
}
}
}
CarouselPage_CurrentPageChanged
方法
private async void CarouselPage_CurrentPageChanged(object sender, EventArgs e)
{
var tokenSource = new CancellationTokenSource();
await Task.Delay(TimeSpan.FromSeconds(3), tokenSource.Token);
MessagingCenter.Subscribe<App, string>(App.Current, "OpenPage", (snd, arg) =>
{
tokenSource.Cancel();
});
int index = Children.IndexOf(CurrentPage);
if (index == 0)
{
CurrentPage = Children[1];
}
else if (index == 1)
{
CurrentPage = Children[2];
}
else if (index == 2)
{
CurrentPage = Children[3];
}
else if (index == 3)
{
CurrentPage = Children[0];
}
}