Xamarin.Forms ScrollView

下载示例 下载示例

Xamarin.Forms ScrollView

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

警告

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

ScrollView 定义以下属性:

这些属性由 BindableProperty 对象支持,但 属性除外 Content ,这意味着它们可以成为数据绑定的目标并设置样式。

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

提示

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

作为根布局的 ScrollView

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

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

注意

在垂直 ScrollView中,避免将 VerticalOptions 属性设置为 StartCenterEnd。 这样做会 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 垂直滚动,显示更多内容:

根 ScrollView 布局的屏幕截图

等效 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可以是不同父布局的子布局。

ScrollView通常是 的子级StackLayoutScrollView需要一个特定的高度来计算其内容的高度与其自身高度之间的差值,其差值是 可以滚动其内容的量ScrollViewScrollView当 是 的子级StackLayout时,它不接收特定高度。 希望 StackLayoutScrollView 尽可能短,即内容的高度 ScrollView 或零。 若要处理这种情况, VerticalOptionsScrollView 属性应设置为 FillAndExpand。 这将导致 StackLayout 提供 ScrollView 其他子级不需要的所有额外空间,然后 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 作为其子级。 ScrollViewStackLayout 作为其内容,其中包含StackLayout多个 Label 对象。 这种排列方式可确保第一个 Label 始终在屏幕上显示,而其他 Label 对象显示的文本可以滚动:

子 ScrollView 布局的屏幕截图

等效 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.ScrollXScrolledEventArgs.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指定位置,而另一个重载将指定的元素滚动到视图中。 这两个重载都有一个附加参数,可用于指示是否对滚动进行动画处理。

重要

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

将位置滚动到视图中

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

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

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

将元素滚动到视图中

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

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

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

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

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

滚动条可见性

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

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