Xamarin.Forms ScrollView

Download Sample サンプルをダウンロードします

Xamarin.Forms ScrollView

ScrollView は、コンテンツをスクロールできるレイアウトです。 クラスは ScrollView クラスから Layout 派生し、既定ではコンテンツを垂直方向にスクロールします。 A ScrollView は 1 人の子しか持つことができませんが、これは他のレイアウトでもかまいません。

警告

ScrollView オブジェクトは入れ子にしないでください。 さらに、オブジェクトは、ScrollViewスクロールを提供する他のコントロール (.、CollectionViewListViewなど) とWebView入れ子にしないでください。

ScrollView は次の特性を定義します。

  • Content(type View) は、.に表示するコンテンツを ScrollView表します。
  • ContentSizeの種類 Sizeは、コンテンツのサイズを表します。 これは、読み取り専用プロパティです。
  • HorizontalScrollBarVisibility(type ScrollBarVisibility) は、水平スクロール バーが表示されるタイミングを表します。
  • OrientationScrollOrientationの 、 のスクロール方向を ScrollView表します。 このプロパティの既定値は Vertical です。
  • ScrollX(type double) は、現在の X スクロール位置を示します。 この読み取り専用プロパティの既定値は 0 です。
  • ScrollY(type double) は、現在の Y スクロール位置を示します。 この読み取り専用プロパティの既定値は 0 です。
  • VerticalScrollBarVisibility(type ScrollBarVisibility) は、垂直スクロール バーが表示されるタイミングを表します。

これらのプロパティは、プロパティを除Contentき、オブジェクトによってBindablePropertyサポートされます。これは、データ バインディングのターゲットとスタイルを設定できることを意味します。

このプロパティはContentContentPropertyクラスのScrollViewプロパティであるため、XAML から明示的に設定する必要はありません。

ヒント

レイアウトパフォーマンスを最大限に高めるには、「レイアウトパフォーマンスの 最適化」のガイドラインに従ってください。

ルート レイアウトとしての ScrollView

A ScrollView には 1 つの子しか含めず、他のレイアウトを使用できます。 そのため、ページのルート レイアウトになるのが一般的 ScrollView です。 子コンテンツをスクロールするには、 ScrollView そのコンテンツの高さとそれ自体の高さの差を計算します。 その違いは、コンテンツを ScrollView スクロールできる量です。

A StackLayout は、多くの場合、の ScrollView子になります. このシナリオでは、 ScrollView その原因 StackLayout は、その子の高さの合計と同じ高さになります。 次に、 ScrollView コンテンツをスクロールできる量を決定できます。 StackLayout の詳細については、「Xamarin.Forms StackLayout」を参照してください。

注意事項

垂直方向ScrollViewでは、プロパティを VerticalOptionsCenterまたは End. にStart設定しないでください。 そうすることで、 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使用して定義されたフィールドXamarin.Formsを表示Colorするコンテンツ セットを a StackLayout に設定しています。 既定では、垂直方向に 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

A ScrollView は、別の親レイアウトに対する子レイアウトにすることができます。

A ScrollView は、多くの場合、の StackLayout子になります. A では ScrollView 、コンテンツの高さとそれ自体の高さの差を計算するために特定の高さが必要です。その違いは、コンテンツを ScrollView スクロールできる量です。 a ScrollView が a の子の場合、特定の StackLayout高さを受け取りません。 これは StackLayout 、コンテンツの ScrollView 高さ ScrollView またはゼロのいずれかである、できるだけ短くしたいと考えています。 このシナリオを処理するには、プロパティを VerticalOptionsScrollViewFillAndExpand. これにより、他の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>

この例では、2 つの StackLayout オブジェクトがあります。 1 つ目StackLayoutは、オブジェクトとそのScrollView子を持つLabelルート レイアウト オブジェクトです。 にはScrollViewStackLayout、複数Labelのオブジェクトを含むコンテンツStackLayoutが含まれています。 この配置により、最初 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 }
        };
    }
}

方向

ScrollViewOrientationのスクロール方向を表すプロパティがありますScrollView。 このプロパティは、次のメンバーを定義する型 ScrollOrientationです。

  • Vertical は、垂直方向に ScrollView スクロールされることを示します。 このメンバーは、プロパティの Orientation 既定値です。
  • Horizontal は、水平に ScrollView スクロールすることを示します。
  • Both は、水平方向と垂直方向にスクロールすることを ScrollView 示します。
  • NeitherScrollView 、スクロールしないことを示します。

ヒント

プロパティNeitherを に設定すると、スクロールをOrientation無効にできます。

スクロールを検出する

ScrollView は、 Scrolled スクロールが発生したことを示すために発生するイベントを定義します。 ScrolledEventArgsイベントに付随Scrolledするオブジェクトには、両方の型doubleのプロパティがありますScrollXScrollY

重要

プロパティとScrolledEventArgs.ScrollYプロパティにはScrolledEventArgs.ScrollX負の値を設定できます。これは、開始位置までスクロールして戻るときに発生するバウンス効果が原因です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 は、非同期的にスクロールする 2 つの ScrollToAsync メソッドを定義します ScrollView。 オーバーロードの 1 つは、指定した位置 ScrollViewまでスクロールし、もう 1 つは指定した要素をビューにスクロールします。 どちらのオーバーロードにも、スクロールをアニメーション化するかどうかを示すために使用できる追加の引数があります。

重要

ScrollToAsyncプロパティが に設定Neitherされている場合ScrollView.Orientation、メソッドはスクロールされません。

位置をビューにスクロールする

a 内のScrollView位置は、受け取doublexるメソッドとy引数をScrollToAsync使用してスクロールできます。 垂直 ScrollView オブジェクトという名前 scrollViewの場合、次の例は、デバイスに依存しない 150 個の単位を上からスクロールする方法を ScrollView示しています。

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

3 番目の ScrollToAsync 引数は animated 引数で、プログラムで ScrollViewスクロールするときにスクロール アニメーションを表示するかどうかを決定します。

要素をビューにスクロールする

a 内のScrollView要素は、受け入れとScrollToPosition引数を受け取Elementるメソッドを使用してScrollToAsyncビューにスクロールできます。 垂直ScrollViewの名前と名前付LabelscrollViewlabelを指定すると、次の例は、要素をビューにスクロールする方法を示しています。

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

3 番目の ScrollToAsync 引数は animated 引数で、プログラムで ScrollViewスクロールするときにスクロール アニメーションを表示するかどうかを決定します。

要素をビューにスクロールする場合、スクロールが完了した後の要素の正確な位置は、 positionメソッドの 2 番目の ScrollToAsync 引数で設定できます。 この引数は、列挙メンバーを ScrollToPosition 受け入れます。

  • MakeVisible は、要素が表示されるまで ScrollViewスクロールする必要があることを示します。
  • Start は、要素を最初 ScrollViewまでスクロールする必要があることを示します。
  • Center は、要素を中央 ScrollViewまでスクロールする必要があることを示します。
  • End は、要素を最後まで ScrollViewスクロールする必要があることを示します。

スクロール バーの表示

ScrollView は、 HorizontalScrollBarVisibility バインド可能なプロパティによってサポートされるプロパティと VerticalScrollBarVisibility 定義します。 これらのプロパティは、水平方向または垂直方向のスクロール バーが表示されるかどうかを表す列挙値を取得または設定 ScrollBarVisibility します。 ScrollBarVisibility 列挙体を使って、次のメンバーを定義できます。

  • Default はプラットフォームの既定のスクロール バーの動作を示し、既定値は and HorizontalScrollBarVisibilityVerticalScrollBarVisibility properties です。
  • Always は、コンテンツがビューに収まる場合でも、スクロール バーが表示されることを示します。
  • Never は、コンテンツがビューに収まらない場合でも、スクロール バーが表示されないことを示します。