Xamarin.Forms CollectionView 滚动

CollectionView 定义两种 ScrollTo 方法,用于将项滚动到视图中。 其中一个重载将指定索引处的项滚动到视图中,而另一个重载将指定的项滚动到视图中。 这两个重载都有额外的参数,可以指定这些参数来指示项所属的组,滚动完成后项的确切位置,以及是否对滚动进行动画处理。

CollectionView 定义调用其中一个 ScrollTo 方法时触发的 ScrollToRequested 事件。 ScrollToRequested 事件附带的 ScrollToRequestedEventArgs 对象有许多属性,包括 IsAnimatedIndexItemScrollToPosition。 这些属性是根据 ScrollTo 方法调用中指定的参数设置的。

此外,CollectionView 还定义了 Scrolled 事件,该事件被触发后表示滚动发生。 Scrolled 事件附带的 ItemsViewScrolledEventArgs 对象有许多属性。 有关详细信息,请参阅检测滚动

CollectionView 还定义了一个 ItemsUpdatingScrollMode 属性,该属性表示 CollectionView 中添加新项目时的滚动行为。 有关此属性的详细信息,请参阅添加新项时的控件滚动位置

当用户轻扫以启动滚动时,可以控制滚动的结束位置,以便完全显示项。 这种功能被称为对齐,因为当滚动停止时,项将按位置对齐。 有关详细信息,请参阅对齐点

CollectionView 还可以在用户滚动时以增量方式加载数据。 有关详细信息,请参阅以增量方式加载数据

检测滚动

CollectionView 定义了一个 Scrolled 事件,该事件被触发以指示发生了滚动。 ItemsViewScrolledEventArgs 类表示 Scrolled 事件随附的对象,它定义下列属性:

  • HorizontalDelta,类型为 double,表示水平滚动量的变化。 向左滚动时此为负值,向右滚动时为正值。
  • VerticalDelta,类型为 double,表示垂直滚动量的变化。 向上滚动时此为负值,向下滚动时为正值。
  • HorizontalOffset,类型为 double,定义列表从其原点水平偏移的量。
  • VerticalOffset,类型为 double,定义列表从其原点垂直偏移的量。
  • FirstVisibleItemIndex,类型为 int,是列表中第一个可见项的索引。
  • CenterItemIndex 类型为 int,是列表中可见的中心项的索引。
  • LastVisibleItemIndex,类型为 int,是列表中可见的最后一项的索引。

下面的 XAML 示例显示了为 Scrolled 事件设置事件处理程序的 CollectionView

<CollectionView Scrolled="OnCollectionViewScrolled">
    ...
</CollectionView>

等效 C# 代码如下:

CollectionView collectionView = new CollectionView();
collectionView.Scrolled += OnCollectionViewScrolled;

在此代码示例中,Scrolled 事件触发时,将执行 OnCollectionViewScrolled 事件处理程序:

void OnCollectionViewScrolled(object sender, ItemsViewScrolledEventArgs e)
{
    // Custom logic
}

重要

会针对用户启动的滚动和编程滚动触发 Scrolled 事件。

将索引处的项滚动到视图中

第一个 ScrollTo 方法重载将指定索引处的项滚动到视图中。 给定一个名为 collectionViewCollectionView 对象,下面的示例显示如何将索引 12 处的项滚动到视图中:

collectionView.ScrollTo(12);

或者通过指定项和组索引,可以将已分组数据中的项滚动到视图中。 以下示例演示如何将第二组中的第三项滚动到视图中:

// Items and groups are indexed from zero.
collectionView.ScrollTo(2, 1);

注意

在调用 ScrollTo 方法时触发 ScrollToRequested 事件。

将项滚动到视图中

第二个 ScrollTo 方法重载将指定项滚动到视图中。 给定一个名为 collectionViewCollectionView 对象,以下示例显示如何将 Proboscis Monkey 项滚动到视图中:

MonkeysViewModel viewModel = BindingContext as MonkeysViewModel;
Monkey monkey = viewModel.Monkeys.FirstOrDefault(m => m.Name == "Proboscis Monkey");
collectionView.ScrollTo(monkey);

或者,可以通过指定项和组来将分组数据中的项滚动到视图中。 以下示例演示如何将“猴子”组中的“长鼻猴”项滚动到视图中:

GroupedAnimalsViewModel viewModel = BindingContext as GroupedAnimalsViewModel;
AnimalGroup group = viewModel.Animals.FirstOrDefault(a => a.Name == "Monkeys");
Animal monkey = group.FirstOrDefault(m => m.Name == "Proboscis Monkey");
collectionView.ScrollTo(monkey, group);

注意

在调用 ScrollTo 方法时触发 ScrollToRequested 事件。

禁用滚动动画

将项滚动到视图中时,将显示滚动动画。 但是,可以通过将 ScrollTo 方法的 animate 参数设置为 false 来禁用此动画:

collectionView.ScrollTo(monkey, animate: false);

控制滚动位置

将项滚动到视图中时,可以使用 ScrollTo 方法的 position 参数指定项在滚动完成后的确切位置。 此参数接受 ScrollToPosition 枚举成员。

MakeVisible

ScrollToPosition.MakeVisible 成员指示应滚动该项,直到它在视图中可见:

collectionView.ScrollTo(monkey, position: ScrollToPosition.MakeVisible);

此示例代码导致将项滚动到视图中所需的最小滚动:

iOS 和 Android 上具有 ScrollToPosition.MakeVisible 的 CollectionView 垂直列表的屏幕截图

注意

如果在调用 ScrollTo 方法时未指定 position 参数,则默认使用 ScrollToPosition.MakeVisible 成员。

开始

ScrollToPosition.Start 成员指示应将项滚动到视图的开头:

collectionView.ScrollTo(monkey, position: ScrollToPosition.Start);

此示例代码导致项滚动到视图的开头:

iOS 和 Android 上具有 ScrollToPosition.Start 的 CollectionView 垂直列表的屏幕截图

中心

ScrollToPosition.Center 成员指示应将项滚动到视图的中心:

collectionView.ScrollTo(monkey, position: ScrollToPosition.Center);

此示例代码导致将项滚动到视图的中心:

iOS 和 Android 上具有 ScrollToPosition.Center 的 CollectionView 垂直列表的屏幕截图

End

ScrollToPosition.End 应将项滚动到视图的末尾:

collectionView.ScrollTo(monkey, position: ScrollToPosition.End);

此示例代码导致将项滚动到视图的末尾:

iOS 和 Android 上具有 ScrollToPosition.End 的 CollectionView 垂直列表的屏幕截图

添加新项时控制滚动位置

CollectionView 定义一个 ItemsUpdatingScrollMode 属性,该属性由可绑定属性支持。 此属性获取或设置一个 ItemsUpdatingScrollMode 枚举值,该值表示向其中添加新项时 CollectionView 的滚动行为。 ItemsUpdatingScrollMode 枚举定义以下成员:

  • KeepItemsInView 在添加新项时,将保留列表中显示的第一项。
  • KeepScrollOffset 确保在添加新项时保持当前滚动位置。
  • KeepLastItemInView 调整滚动偏移量,以在添加新项时保留列表中显示的最后一项。

ItemsUpdatingScrollMode 属性的默认值是 KeepItemsInView。 因此,将新项添加到 CollectionView 时,将保持显示列表中的第一个项。 若要确保在添加新项时显示列表中的最后一项,应将 ItemsUpdatingScrollMode 属性设置为 KeepLastItemInView

<CollectionView ItemsUpdatingScrollMode="KeepLastItemInView">
    ...
</CollectionView>

等效 C# 代码如下:

CollectionView collectionView = new CollectionView
{
    ItemsUpdatingScrollMode = ItemsUpdatingScrollMode.KeepLastItemInView
};

滚动条可见性

CollectionView 定义 HorizontalScrollBarVisibilityVerticalScrollBarVisibility 属性,它们由可绑定的属性提供支持。 这些属性会获取或设置一个 ScrollBarVisibility 枚举值,指示水平滚动条或垂直滚动条何时可见。 ScrollBarVisibility 枚举定义以下成员:

  • Default 指示平台的默认滚动条行为,并且是 HorizontalScrollBarVisibilityVerticalScrollBarVisibility 属性的默认值。
  • Always 指示滚动条将可见,即使内容大小适合视图。
  • Never 指示滚动条将不可见,即使内容大小不适合视图。

贴靠点

当用户轻扫以启动滚动时,可以控制滚动的结束位置,以便完全显示项。 这种功能被称为对齐,因为项在滚动停止时会对齐到位置,并且由 ItemsLayout 类中的以下属性控制:

这些属性由 BindableProperty 对象提供支持,这意味着它们可以作为数据绑定的目标。

注意

当对齐发生时,它将发生在产生最小运动量的方向上。

对齐点类型

SnapPointsType 枚举定义以下成员:

  • None 指示滚动不会对齐到项。
  • Mandatory 表示内容总是沿惯性方向对齐到最接近滚动自然停止位置的对齐点。
  • MandatorySingle 表示与 Mandatory 相同的行为,但一次只能滚动一个项。

默认情况下,SnapPointsType 属性设置为 SnapPointsType.None,这样可确保滚动不会对齐项,如以下屏幕截图所示:

iOS 和 Android 上不含对齐点的 CollectionView 垂直列表的屏幕截图

对齐点对齐

SnapPointsAlignment 枚举定义 StartCenterEnd 成员。

重要

只有当 SnapPointsType 属性设置为 MandatoryMandatorySingle 时,才会考虑 SnapPointsAlignment 属性的值。

开始

SnapPointsAlignment.Start 成员指示对齐点与项的前边缘对齐。

默认情况下,SnapPointsAlignment 属性设置为 SnapPointsAlignment.Start。 但是,为完整起见,下面的 XAML 示例展示了如何设置此枚举成员:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           SnapPointsType="MandatorySingle"
                           SnapPointsAlignment="Start" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

等效 C# 代码如下:

CollectionView collectionView = new CollectionView
{
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        SnapPointsType = SnapPointsType.MandatorySingle,
        SnapPointsAlignment = SnapPointsAlignment.Start
    },
    // ...
};

当用户轻扫以启动滚动时,顶部项将与视图的顶部对齐:

iOS 和 Android 上具有起始对齐点的 CollectionView 垂直列表的屏幕截图

中心

SnapPointsAlignment.Center 成员指示对齐点与项的中心对齐。 以下 XAML 示例展示了如何设置此枚举成员:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           SnapPointsType="MandatorySingle"
                           SnapPointsAlignment="Center" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

等效 C# 代码如下:

CollectionView collectionView = new CollectionView
{
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        SnapPointsType = SnapPointsType.MandatorySingle,
        SnapPointsAlignment = SnapPointsAlignment.Center
    },
    // ...
};

当用户轻扫以启动滚动时,顶部项将在视图顶部居中对齐:

iOS 和 Android 上具有中心对齐点的 CollectionView 垂直列表的屏幕截图

End

SnapPointsAlignment.End 成员指示对齐点与项的尾部对齐。 以下 XAML 示例展示了如何设置此枚举成员:

<CollectionView ItemsSource="{Binding Monkeys}">
    <CollectionView.ItemsLayout>
        <LinearItemsLayout Orientation="Vertical"
                           SnapPointsType="MandatorySingle"
                           SnapPointsAlignment="End" />
    </CollectionView.ItemsLayout>
    ...
</CollectionView>

等效 C# 代码如下:

CollectionView collectionView = new CollectionView
{
    ItemsLayout = new LinearItemsLayout(ItemsLayoutOrientation.Vertical)
    {
        SnapPointsType = SnapPointsType.MandatorySingle,
        SnapPointsAlignment = SnapPointsAlignment.End
    },
    // ...
};

当用户轻扫以启动滚动时,底部项将与视图的底部对齐:

iOS 和 Android 上具有结束对齐点的 CollectionView 垂直列表的屏幕截图