Xamarin自定义布局系列——PivotPage(多页面切换控件)

PivotPage ———— 多页面切换控件

PivotPage是一个多页面切换控件,类似安卓中的ViewPager和UWP中的Pivot枢轴控件。

起初打算直接通过ScrollView+StackLayout直接实现该控件,但是在具体实现的时候,发现iOS中,利用UIScrollView的PagingEnabled 属性,可以很方便的实现分页效果。但是,在安卓平台中,原生的ScrollView只提供了很有限的事件方法,需要比较绕的操作才能实现诸如滚动开始,滚动停止等事件的监听,极其不便,所以直接利用ViewPager实现多页面切换的效果。

又考虑到在Xamarin.Forms层面,应该有同意的方法实现页面切换等操作,和具体平台相互隔离
所以使用了一个自定义控件ViewPanel,该控件继承自ScrollView

为什么ViewPanel不直接继承自View呢?
  1. 在安卓平台中,无论是View还是ScrollView,最后都要通过ViewRenderer用ViewPager来实现,没有区别。

  2. 在iOS中,情况有些不同。应为iOS中该控件基本都是用FORMS直接实现的,唯一用到的Renderer是ScrollViewRenderer,用来设置ScrollView对应的UIScrollView的PagingEnabled属性,让滚动条按页滑动,所以让ViewPanel直接继承自ScrollView,省去一些不必要的代码

如何实现在ViewPanel中显示自定义的控件?

在iOS中,ViewPanel是由ScrollView+StackLayout直接实现的,所以把我们自定义的View直接添加到StackLayout中就可以了,代码实现类似于:

    ···
    _stackLaout.Children.Add(view);
    ···

在Android中,ViewPanel由一个ViewPager实现,ViewPanel为ViewPager提供所有的子元素,利用如下方法添加到ViewPager中:
(来资源PageAdapter)

    public override Java.Lang.Object InstantiateItem(Android.Views.View container, int position)
    {

        var viewPager = container.JavaCast<ViewPager>();

        var view = _views[position] as Xamarin.Forms.View;

        view.Parent = _customViewPage;

        if (Platform.GetRenderer(view) == null)

            Platform.SetRenderer(view, Platform.CreateRenderer(view));

        var renderer = Platform.GetRenderer(view);

        var viewGroup = renderer.ViewGroup;

        viewPager.AddView(viewGroup);

        return viewGroup;

    }

使用ViewPager的时候,数据由PageAdapter提供。根据我们提供的View,创建相应的NativeView添加到ViewPager中。


控件由两部分组成:

  1. Header:放置各个页面标题,LOGO等,数据模板自定义,支持数据绑定
  2. Views:自定义控件ViewPanel,继承自ScrollView(主要方便iOS),安卓中不使用ScrollView的任何特性,只当作简单的View

注意:使用的时候需要自定义两个集合,一个存放Views,一个存放Header,二者中元素一一对应,由使用者维护

(在MVVM中使用举例)

    Headers.Add(new PivotItemModel { Title = "Mokey" });
    Views.Add(new MokeyView());
    Headers.Add(new PivotItemModel { Title = "Test" });
    Views.Add(new TestView());

目前实现的版本

  • iOS:利用Xamarin.Fomrs中SrollView+StackLayout实现ViewPanel
  • Android:直接使用ViewPager实现ViewPanel

Demo

GitHub地址:PivotPage

转载于:https://www.cnblogs.com/cjw1115/p/6569364.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在移动应用开发中,自动轮播视图是一个非常常见的控件,它可以帮助用户展示多个图片或者内容,使得应用更加生动、丰富。但是在Xamarin中,自动轮播视图并没有原生的控件,需要通过自定义布局来实现。本文将介绍如何使用CarouselView实现支持无限滚动的自动轮播视图。 ## 1. CarouselView简介 CarouselView是一个基于Xamarin.Forms的自定义布局,它可以帮助我们实现类似于ViewPager的效果,支持水平和垂直滚动,并且可以无限滚动。它的主要特点包括: - 支持多种布局方式,包括Stack、Wrap、Grid等。 - 支持水平和垂直滚动,以及无限滚动。 - 支持手势滑动和自动轮播。 - 提供了各种事件,方便我们进行自定义操作。 ## 2. 安装CarouselView 要使用CarouselView,我们首先需要将其添加到我们的项目中。我们可以通过NuGet包管理器来安装CarouselView,具体操作如下: 1. 在Visual Studio中打开我们的移动应用项目。 2. 打开NuGet包管理器,可以通过菜单栏中的“工具”->“NuGet包管理器”->“管理解决方案的NuGet包”打开。 3. 在NuGet包管理器中搜索“CarouselView.FormsPlugin”,并安装它。 安装完成后,我们就可以在项目中使用CarouselView了。 ## 3. 使用CarouselView 在使用CarouselView之前,我们需要在XAML文件中添加CarouselView的命名空间: ```xml xmlns:cv="clr-namespace:CarouselView.FormsPlugin.Abstractions;assembly=CarouselView.FormsPlugin.Abstractions" ``` 然后在我们的布局中添加CarouselView控件: ```xml <cv:CarouselView x:Name="carouselView" ItemsSource="{Binding ImageUrls}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Orientation="Horizontal" PositionSelected="OnPositionSelected"> <cv:CarouselView.ItemTemplate> <DataTemplate> <Image Source="{Binding .}" Aspect="AspectFill" /> </DataTemplate> </cv:CarouselView.ItemTemplate> </cv:CarouselView> ``` 上述代码中,我们使用了一个绑定ImageUrls的集合作为CarouselView的数据源,每一个Item都是一个Image控件。我们还可以通过设置HorizontalOptions和VerticalOptions来控制CarouselView的布局方式,设置Orientation来控制滚动的方向。 在代码中,我们可以通过PositionSelected事件来监听当前选中的位置,然后进行自定义操作: ```csharp private void OnPositionSelected(object sender, PositionSelectedEventArgs e) { // Do something } ``` ## 4. 实现无限滚动 上述代码中的CarouselView实现了基本的自动轮播效果,但是它并不能无限滚动。当滚动到最后一个Item时,就会停止滚动,用户需要手动操作才能再次滚动。 要实现无限滚动,我们需要通过自定义布局来实现。具体操作如下: 1. 创建一个新的CarouselView控件,继承自CarouselView控件。 ```csharp public class InfiniteCarouselView : CarouselViewControl { //... } ``` 2. 在控件中实现一个循环滚动的方法,用于在滚动到最后一个Item时将其移动到第一个Item。 ```csharp private void LoopScroll(int position) { if (position == ItemsSource.Count - 1) { Task.Delay(200).ContinueWith(t => { Device.BeginInvokeOnMainThread(() => { this.Position = 0; }); }); } } ``` 3. 在控件的构造函数中监听PositionSelected事件,当滚动到最后一个Item时调用LoopScroll方法。 ```csharp public InfiniteCarouselView() { PositionSelected += (sender, e) => { LoopScroll(e.NewValue); }; } ``` 4. 在页面中使用我们自定义的CarouselView控件。 ```xml <local:InfiniteCarouselView x:Name="carouselView" ItemsSource="{Binding ImageUrls}" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Orientation="Horizontal"> <cv:CarouselView.ItemTemplate> <DataTemplate> <Image Source="{Binding .}" Aspect="AspectFill" /> </DataTemplate> </cv:CarouselView.ItemTemplate> </local:InfiniteCarouselView> ``` 通过以上步骤,我们就可以实现一个支持无限滚动的自动轮播视图了。完整代码示例可以参考我的Github仓库:https://github.com/wangxizhe/CarouselViewDemo 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值