Xamarin.Forms ScrollView

Download Sample 下载示例

Xamarin.Forms ScrollView

ScrollView 是能够滚动其内容的布局。 类 ScrollView 派生自 Layout 该类,默认情况下垂直滚动其内容。 一个 ScrollView 只能有一个子级,尽管这可以是其他布局。

警告

ScrollView 不应嵌套对象。 此外, ScrollView 不应与提供滚动的其他控件(例如 CollectionViewListViewWebView)嵌套对象。

ScrollView 定义以下属性:

这些属性由 BindableProperty 对象提供支持,但属性除外 Content ,这意味着这些属性可以是数据绑定和样式的目标。

Content 属性是 ContentProperty 类的 ScrollView ,因此不需要从 XAML 显式设置。

提示

若要获得最佳布局性能,请遵循 “优化布局性能”中的准则。

ScrollView 作为根布局

A ScrollView 只能有一个子级,可以是其他布局。 因此,页面的根布局很常见 ScrollView 。 若要滚动其子内容, ScrollView 请计算其内容高度与自身高度之间的差异。 这种差异是可滚动其内容的数量 ScrollView

A StackLayout 通常为 a ScrollView的子级。 在此方案中,导致ScrollViewStackLayout其子级的高度之和相同。 然后, ScrollView 可以确定可滚动其内容的数量。 有关 StackLayout 的详细信息,请参阅 StackLayoutXamarin.Forms

注意

在垂直 ScrollView方向上,请避免将 VerticalOptions 属性 Start设置为, CenterEnd。 这样做会告知 ScrollView 它只有像它一样高,这可能是零。 虽然 Xamarin.Forms 可以防范这种可能性,但最好避免代码建议你不想发生的内容。

下面的 XAML 示例在页面上具有 ScrollView 作为根布局:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:ScrollViewDemos"
             x:Class="ScrollViewDemos.Views.ColorListPage"
             Title="ScrollView demo">
    <ScrollView>
        <StackLayout BindableLayout.ItemsSource="{x:Static local:NamedColor.All}">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <StackLayout Orientation="Horizontal">
                        <BoxView Color="{Binding Color}"
                                 HeightRequest="32"
                                 WidthRequest="32"
                                 VerticalOptions="Center" />
                        <Label Text="{Binding FriendlyName}"
                               FontSize="24"
                               VerticalOptions="Center" />
                    </StackLayout>
                </DataTemplate>
            </BindableLayout.ItemTemplate>
        </StackLayout>
    </ScrollView>
</ContentPage>

在此示例中,其 ScrollView 内容集设置为 StackLayout 使用可绑定布局显示 Color 由 Xamarin.Forms其定义的字段。 默认情况下, ScrollView 垂直滚动显示更多内容:

Screenshot of a root ScrollView layout

等效 C# 代码如下:

public class ColorListPageCode : ContentPage
{
    public ColorListPageCode()
    {
        DataTemplate dataTemplate = new DataTemplate(() =>
        {
            BoxView boxView = new BoxView
            {
                HeightRequest = 32,
                WidthRequest = 32,
                VerticalOptions = LayoutOptions.Center
            };
            boxView.SetBinding(BoxView.ColorProperty, "Color");

            Label label = new Label
            {
                FontSize = 24,
                VerticalOptions = LayoutOptions.Center
            };
            label.SetBinding(Label.TextProperty, "FriendlyName");

            StackLayout horizontalStackLayout = new StackLayout
            {
                Orientation = StackOrientation.Horizontal,
                Children = { boxView, label }
            };
            return horizontalStackLayout;
        });

        StackLayout stackLayout = new StackLayout();
        BindableLayout.SetItemsSource(stackLayout, NamedColor.All);
        BindableLayout.SetItemTemplate(stackLayout, dataTemplate);

        ScrollView scrollView = new ScrollView { Content = stackLayout };

        Title = "ScrollView demo";
        Content = scrollView;
    }
}

有关可绑定布局的详细信息,请参阅可绑定布局。Xamarin.Forms

ScrollView 作为子布局

可以是 ScrollView 不同父布局的子布局。

A ScrollView 通常为 a StackLayout的子级。 A ScrollView 需要特定高度来计算其内容高度与自身高度之间的差值,区别在于可滚动其内容的数量 ScrollView 。 当 a ScrollView 是 a StackLayout的子级时,它不会收到特定的高度。 希望StackLayoutScrollView尽可能短,即内容的高度ScrollView或零。 若要处理此方案, VerticalOptions 应将属性 ScrollView 设置为 FillAndExpand。 这将导致 StackLayoutScrollView 其他子级不需要的所有额外空间,然后 ScrollView 具有特定的高度。

以下 XAML 示例具有ScrollView子布局到 :StackLayout

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ScrollViewDemos.Views.BlackCatPage"
             Title="ScrollView as a child layout demo">
    <StackLayout Margin="20">
        <Label Text="THE BLACK CAT by Edgar Allan Poe"
               FontSize="Medium"
               FontAttributes="Bold"
               HorizontalOptions="Center" />
        <ScrollView VerticalOptions="FillAndExpand">
            <StackLayout>
                <Label Text="FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects." />
                <!-- More Label objects go here -->
            </StackLayout>
        </ScrollView>
    </StackLayout>
</ContentPage>

在此示例中,有两个 StackLayout 对象。 第一 StackLayout 个是根布局对象,该对象具有一个 Label 对象及其 ScrollView 子级。 具有 ScrollView 一个 StackLayout 作为其内容的内容,其中包含 StackLayout 多个 Label 对象。 这种排列可确保第一个 Label 始终在屏幕上显示,而其他 Label 对象显示的文本可以滚动:

Screenshot of a child ScrollView layout

等效 C# 代码如下:

public class BlackCatPageCS : ContentPage
{
    public BlackCatPageCS()
    {
        Label titleLabel = new Label
        {
            Text = "THE BLACK CAT by Edgar Allan Poe",
            // More properties set here to define the Label appearance
        };

        ScrollView scrollView = new ScrollView
        {
            VerticalOptions = LayoutOptions.FillAndExpand,
            Content = new StackLayout
            {
                Children =
                {
                    new Label
                    {
                        Text = "FOR the most wild, yet most homely narrative which I am about to pen, I neither expect nor solicit belief. Mad indeed would I be to expect it, in a case where my very senses reject their own evidence. Yet, mad am I not -- and very surely do I not dream. But to-morrow I die, and to-day I would unburthen my soul. My immediate purpose is to place before the world, plainly, succinctly, and without comment, a series of mere household events. In their consequences, these events have terrified -- have tortured -- have destroyed me. Yet I will not attempt to expound them. To me, they have presented little but Horror -- to many they will seem less terrible than barroques. Hereafter, perhaps, some intellect may be found which will reduce my phantasm to the common-place -- some intellect more calm, more logical, and far less excitable than my own, which will perceive, in the circumstances I detail with awe, nothing more than an ordinary succession of very natural causes and effects.",
                    },
                    // More Label objects go here
                }
            }
        };

        Title = "ScrollView as a child layout demo";
        Content = new StackLayout
        {
            Margin = new Thickness(20),
            Children = { titleLabel, scrollView }
        };
    }
}

方向

ScrollView 具有一个 Orientation 属性,表示滚动方向 ScrollView。 此属性的类型 ScrollOrientation,定义以下成员:

  • Vertical 指示 ScrollView 将垂直滚动。 此成员是属性的 Orientation 默认值。
  • Horizontal 指示 ScrollView 将水平滚动。
  • Both 指示 ScrollView 将水平和垂直滚动。
  • Neither 指示 ScrollView 不会滚动。

提示

通过将属性设置为 OrientationNeither.,可以禁用滚动。

检测滚动

ScrollView 定义触发 Scrolled 的事件,以指示发生滚动。 ScrolledEventArgs事件附带Scrolled的对象具有ScrollXScrollY属性,这两种类型double

重要

ScrolledEventArgs.ScrollX属性ScrolledEventArgs.ScrollY可以具有负值,因为回退到开始ScrollView时出现的弹跳效果。

下面的 XAML 示例演示了一个 ScrollView 设置事件的事件处理程序 Scrolled

<ScrollView Scrolled="OnScrollViewScrolled">
		...
</ScrollView>

等效 C# 代码如下:

ScrollView scrollView = new ScrollView();
scrollView.Scrolled += OnScrollViewScrolled;

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

void OnScrollViewScrolled(object sender, ScrolledEventArgs e)
{
    Console.WriteLine($"ScrollX: {e.ScrollX}, ScrollY: {e.ScrollY}");
}

在此示例中, OnScrollViewScrolled 事件处理程序输出事件附带的对象的值 ScrolledEventArgs

注意

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

以编程方式滚动

ScrollView 定义两 ScrollToAsync 个异步滚动 ScrollView的方法。 其中一个重载滚动到指定位置, ScrollView而另一个重载将指定元素滚动到视图中。 这两个重载都有一个附加参数,可用于指示是否对滚动进行动画处理。

重要

当属性设置为 Neither.时ScrollView.Orientation,方法ScrollToAsync不会导致滚动。

将位置滚动到视图中

可以使用接受double和参数的方法滚动到ScrollToAsync某个位置ScrollViewyx 给定命名scrollView的垂直ScrollView对象,以下示例演示如何从顶部滚动到 150 个与设备无关的ScrollView单位:

await scrollView.ScrollToAsync(0, 150, true);

第三个参数是animated参数ScrollToAsync,它确定在以编程方式滚动 a ScrollView时是否显示滚动动画。

将元素滚动到视图中

可以使用接受和ScrollToPosition参数的方法滚动到视图中ScrollToAsync的元素ScrollViewElement 给定垂直 ScrollView 命名 scrollView的名称和 Label 命名 label名称,以下示例演示如何将元素滚动到视图中:

await scrollView.ScrollToAsync(label, ScrollToPosition.End, true);

第三个参数是animated参数ScrollToAsync,它确定在以编程方式滚动 a ScrollView时是否显示滚动动画。

将元素滚动到视图中时,可以使用方法的第二个参数positionScrollToAsync设置滚动完成后元素的确切位置。 此参数接受 ScrollToPosition 枚举成员:

  • MakeVisible 指示元素应滚动,直到元素在中 ScrollView可见为止。
  • Start 指示元素应滚动到开头 ScrollView
  • Center 指示元素应滚动到中心 ScrollView
  • End 指示元素应滚动到末尾 ScrollView

滚动条可见性

ScrollViewHorizontalScrollBarVisibility定义和VerticalScrollBarVisibility属性,这些属性由可绑定属性提供支持。 这些属性获取或设置一个 ScrollBarVisibility 枚举值,该值表示水平滚动条还是垂直滚动条可见。 ScrollBarVisibility 枚举定义下列成员:

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