次の方法で共有


Xamarin.Forms FlexLayout

"子ビューのコレクションをスタックまたはラップする場合は、FlexLayout を使用します。"

Xamarin.FormsFlexLayout は、Xamarin.Forms バージョン 3.0 の新機能です。 CSS フレキシブル ボックス レイアウト モジュールに基づいており、一般に "フレックス レイアウト" または "フレックスボックス" と呼ばれます。そのように呼ばれるのは、レイアウト内に子を配置するための柔軟なオプションを多数含んでいるからです。

FlexLayout は、スタック内で子を横方向と縦方向に配置できる点で、Xamarin.FormsStackLayout に似ています。 ただし、FlexLayout では、子が多すぎて 1 つの行または列に収まらない場合に、子をラップすることもできます。また、向き、配置、さまざまな画面サイズへの適応などの多くのオプションもあります。

FlexLayoutLayout<View> から派生し、IList<View> 型の Children プロパティを継承します。

FlexLayout では、子要素のサイズ、向き、配置に影響を与える 6 つのバインド可能なパブリック プロパティと、5 つのアタッチされたバインド可能なプロパティが定義されています。 (アタッチされたバインド可能なプロパティの詳細については、記事「添付プロパティ」を参照してください)。これらのプロパティの詳細については、後述の「バインド可能なプロパティの詳細」と「アタッチされたバインド可能なプロパティの詳細」セクションで詳しく説明します。 ただし、この記事では、これらのプロパティの多くを形式ばらずに説明する「FlexLayout一般的な使用シナリオ」セクションから始めます。 この記事の最後に、FlexLayoutCSS スタイル シートと結合させる方法について説明します。

一般的な利用シナリオ

サンプル プログラムには、FlexLayout の一般的な使用方法を示すページがいくつか含まれており、そのプロパティを試すことができます。

単純なスタックに FlexLayout を使用する

[Simple Stack] (単純なスタック) ページには、StackLayout の代わりに FlexLayout を、よりシンプルなマークアップで使用する方法が示されています。 このサンプルのすべてが XAML ページで定義されています。 FlexLayout には 4 つの子が含まれています。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.SimpleStackPage"
             Title="Simple Stack">

    <FlexLayout Direction="Column"
                AlignItems="Center"
                JustifyContent="SpaceEvenly">

        <Label Text="FlexLayout in Action"
               FontSize="Large" />

        <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />

        <Button Text="Do-Nothing Button" />

        <Label Text="Another Label" />
    </FlexLayout>
</ContentPage>

iOS、Android、ユニバーサル Windows プラットフォーム での実行結果を次に示します。

[Simple Stack] ページ

FlexLayout の 3 つのプロパティが、SimpleStackPage.xaml ファイルに表示されます。

  • Direction プロパティは、FlexDirection 列挙型の値に設定されます。 既定値は、Row です。 プロパティを Column に設定すると、FlexLayout の子が項目の 1 つの列に配置されます。

    FlexLayout の項目が列に配置されると、FlexLayout には縦方向の "主軸" と横方向の "交差軸" が設定されると考えられます。

  • AlignItems プロパティは、FlexAlignItems 型であり、項目を交差軸に配置する方法を指定します。 Center オプションを使用すると、各項目が横方向に中央揃えされます。

    このタスクに FlexLayout ではなく StackLayout を使用していた場合は、各項目の HorizontalOptions プロパティを Center に割り当てることで、すべての項目が中央揃えされます。 HorizontalOptions プロパティは、FlexLayout の子に対しては機能しませんが、1 つの AlignItems プロパティで同じ目的を達成できます。 必要に応じて、アタッチされたバインド可能な AlignSelf プロパティを使用して、個々の項目の AlignItems プロパティをオーバーライドすることができます。

    <Label Text="FlexLayout in Action"
           FontSize="Large"
           FlexLayout.AlignSelf="Start" />
    

    この変更により、この Label は、読み取り順序が左から右の場合に、FlexLayout の左端に配置されます。

  • JustifyContent プロパティは、FlexJustify 型であり、項目を主軸に配置する方法を指定します。 SpaceEvenly オプションは、すべての項目の間、最初の項目の上、最後の項目の下に残っているすべての縦方向のスペースを均等に割り当てます。

    もし StackLayout を使用しているとしたら、同様の効果を得るために各項目の VerticalOptions プロパティを CenterAndExpand に割り当てる必要があるでしょう。 ただし、CenterAndExpand オプションでは、最初の項目の前と最後の項目の後の 2 倍のスペースが各項目の間に割り当てられます。 FlexLayoutJustifyContent プロパティを SpaceAround に設定することで、VerticalOptionsCenterAndExpand オプションを模倣できます。

これらの FlexLayout プロパティについては、後述の「バインド可能なプロパティの詳細」セクションで詳しく説明します。

FlexLayout を使用して項目をラップする

サンプルの [Photo Wrapping] ページでは、FlexLayout で子を追加の行または列にラップする方法を示しています。 XAML ファイルは、FlexLayout のインスタンスを作成し、その 2 つのプロパティを割り当てます。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FlexLayoutDemos.PhotoWrappingPage"
             Title="Photo Wrapping">
    <Grid>
        <ScrollView>
            <FlexLayout x:Name="flexLayout"
                        Wrap="Wrap"
                        JustifyContent="SpaceAround" />
        </ScrollView>

        <ActivityIndicator x:Name="activityIndicator"
                           IsRunning="True"
                           VerticalOptions="Center" />
    </Grid>
</ContentPage>

この FlexLayoutDirection プロパティは設定されていないため、Row の既定の設定を使用します。つまり、子は行に配置され、主軸は横方向になります。

Wrap プロパティは、FlexWrap 列挙型です。 項目が多すぎて行に収まらない場合は、このプロパティ設定により、項目が次の行にラップされます。

FlexLayoutScrollView の子であることに注意してください。 行が多すぎてページに収まらなくても、ScrollView には既定で VerticalOrientation プロパティがあるため、縦スクロールが可能です。

JustifyContent プロパティは、各項目が同じ量の空白スペースで囲まれるように、主軸 (横軸) に残りのスペースを割り当てます。

分離コード ファイルは、サンプル写真のコレクションにアクセスし、それらを FlexLayoutChildren コレクションに追加します。

public partial class PhotoWrappingPage : ContentPage
{
    // Class for deserializing JSON list of sample bitmaps
    [DataContract]
    class ImageList
    {
        [DataMember(Name = "photos")]
        public List<string> Photos = null;
    }

    public PhotoWrappingPage ()
    {
        InitializeComponent ();

        LoadBitmapCollection();
    }

    async void LoadBitmapCollection()
    {
        using (WebClient webClient = new WebClient())
        {
            try
            {
                // Download the list of stock photos
                Uri uri = new Uri("https://raw.githubusercontent.com/xamarin/docs-archive/master/Images/stock/small/stock.json");
                byte[] data = await webClient.DownloadDataTaskAsync(uri);

                // Convert to a Stream object
                using (Stream stream = new MemoryStream(data))
                {
                    // Deserialize the JSON into an ImageList object
                    var jsonSerializer = new DataContractJsonSerializer(typeof(ImageList));
                    ImageList imageList = (ImageList)jsonSerializer.ReadObject(stream);

                    // Create an Image object for each bitmap
                    foreach (string filepath in imageList.Photos)
                    {
                        Image image = new Image
                        {
                            Source = ImageSource.FromUri(new Uri(filepath))
                        };
                        flexLayout.Children.Add(image);
                    }
                }
            }
            catch
            {
                flexLayout.Children.Add(new Label
                {
                    Text = "Cannot access list of bitmap files"
                });
            }
        }

        activityIndicator.IsRunning = false;
        activityIndicator.IsVisible = false;
    }
}

上から下に徐々にスクロールされるプログラムは次のとおりです。

[Photo Wrapping] ページ

FlexLayout を使用したページ レイアウト

非常に望ましいとは言え、完璧に実現するのが難しいことが多いレイアウト形式なので聖杯と呼ばれる、ウェブデザインの標準レイアウトがあります。 レイアウトは、ページ上部のヘッダーと下部のフッターで構成され、どちらもページの全幅にまで及びます。 ページの中央を占めるのはメインコンテンツですが、多くの場合、コンテンツの左側に列メニューがあり、右側には補足情報 (アサイド領域とも呼ばれます) があります。 セクション 5.4.1 の CSS フレキシブル ボックス レイアウト仕様では、フレックス ボックスを使用して理想のレイアウトを実現する方法について説明します。

サンプルの [Holy Grail Layout] ページには、別のものに入れ子になった FlexLayout を使用したこのレイアウトのシンプルな実装が示されています。 このページは、電話用にポートレート モードでデザインされているため、コンテンツ部分の左右にある領域の幅は 50 ピクセルしかありません。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="FlexLayoutDemos.HolyGrailLayoutPage"
             Title="Holy Grail Layout">

    <FlexLayout Direction="Column">

        <!-- Header -->
        <Label Text="HEADER"
               FontSize="Large"
               BackgroundColor="Aqua"
               HorizontalTextAlignment="Center" />

        <!-- Body -->
        <FlexLayout FlexLayout.Grow="1">

            <!-- Content -->
            <Label Text="CONTENT"
                   FontSize="Large"
                   BackgroundColor="Gray"
                   HorizontalTextAlignment="Center"
                   VerticalTextAlignment="Center"
                   FlexLayout.Grow="1" />

            <!-- Navigation items-->
            <BoxView FlexLayout.Basis="50"
                     FlexLayout.Order="-1"
                     Color="Blue" />

            <!-- Aside items -->
            <BoxView FlexLayout.Basis="50"
                     Color="Green" />

        </FlexLayout>

        <!-- Footer -->
        <Label Text="FOOTER"
               FontSize="Large"
               BackgroundColor="Pink"
               HorizontalTextAlignment="Center" />
    </FlexLayout>
</ContentPage>

実行すると次のようになります。

[Holy Grail Layout] ページ

ナビゲーション領域とアサイド領域は、BoxView を使用して左と右にレンダリングされます。

XAML ファイルの 1 つ目の FlexLayout には縦方向の主軸があり、3 つの子が 1 つの列に配置されています。 これらはヘッダー、ページの本文、フッターです。 入れ子になった FlexLayout には、横方向の主軸があり、3 つの子が 1 つの行に配置されています。

このプログラムでは、次の 3 つのアタッチされたバインド可能なプロパティについて説明します。

  • アタッチされたバインド可能な Order プロパティが、最初の BoxView に設定されます。 このプロパティは整数で、既定値は 0 です。 このプロパティを使用して、レイアウトの順序を変更できます。 一般に、開発者は、ページのコンテンツが、ナビゲーション項目やアサイド項目より先にマークアップに表示されることを好みます。 最初の BoxViewOrder プロパティを他の兄弟よりも小さい値に設定すると、行の最初の項目として表示されます。 同様に、Order プロパティを兄弟よりも大きい値に設定することで、項目が最後に表示されるようにすることもできます。

  • アタッチされたバインド可能な Basis プロパティは、幅が 50 ピクセルになるように、2 つの BoxView 項目に設定されます。 このプロパティは、FlexBasis 型で、Auto という名前の FlexBasis 型の静的プロパティを定義する構造体であり、既定で設定されています。 Basis を使用すると、項目が占有している主軸上のスペースを示すピクセル サイズまたはパーセンテージを指定できます。 後続のすべてのレイアウトの基準となる項目サイズを指定するため、"基準" と呼ばれています。

  • Grow プロパティは、入れ子になった Layout と、コンテンツを表す Label の子に設定されます。 このプロパティは float 型で、既定値は 0 です。 正の値に設定すると、主軸方向の残りのスペースがすべて、その項目と Grow の正の値を持つ兄弟に割り当てられます。 このスペースは、Grid の星仕様のように、値に比例して割り当てられます。

    1 つ目の Grow 添付プロパティは、入れ子になった FlexLayout に設定され、この FlexLayout が外側の FlexLayout 内にある未使用の縦方向スペースをすべて占有することを示しています。 2 つ目の Grow 添付プロパティは、コンテンツを表す Label に設定され、このコンテンツが内側の FlexLayout 内にある未使用の横方向スペースを占有することを示しています。

    また、子のサイズが FlexLayout のサイズを超えているが、ラップが望ましくない場合に使用できる、類似のアタッチされたバインド可能な Shrink プロパティもあります。

FlexLayout を使用したカタログ項目

サンプルの [Catalog Items] ページは、セクション 1.1 の CSS フレックス レイアウト ボックス仕様の例 1 に似ていますが、横方向にスクロール可能な画像と 3 匹のサルの説明が表示される点が異なります。

[Catalog Items] ページ

3 匹のサルはそれぞれ、高さと幅を明示的に指定する Frame に含まれる FlexLayout であり、より大きな FlexLayout の子でもあります。 この XAML ファイルでは、FlexLayout の子のほとんどのプロパティがスタイルで指定されており、そのうちの 1 つを除くすべてが暗黙的なスタイルです。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.CatalogItemsPage"
             Title="Catalog Items">
    <ContentPage.Resources>
        <Style TargetType="Frame">
            <Setter Property="BackgroundColor" Value="LightYellow" />
            <Setter Property="BorderColor" Value="Blue" />
            <Setter Property="Margin" Value="10" />
            <Setter Property="CornerRadius" Value="15" />
        </Style>

        <Style TargetType="Label">
            <Setter Property="Margin" Value="0, 4" />
        </Style>

        <Style x:Key="headerLabel" TargetType="Label">
            <Setter Property="Margin" Value="0, 8" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="TextColor" Value="Blue" />
        </Style>

        <Style TargetType="Image">
            <Setter Property="FlexLayout.Order" Value="-1" />
            <Setter Property="FlexLayout.AlignSelf" Value="Center" />
        </Style>

        <Style TargetType="Button">
            <Setter Property="Text" Value="LEARN MORE" />
            <Setter Property="FontSize" Value="Large" />
            <Setter Property="TextColor" Value="White" />
            <Setter Property="BackgroundColor" Value="Green" />
            <Setter Property="BorderRadius" Value="20" />
        </Style>
    </ContentPage.Resources>

    <ScrollView Orientation="Both">
        <FlexLayout>
            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Seated Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
                    <Label Text="  &#x2022; Doesn't make a lot of noise" />
                    <Label Text="  &#x2022; Often smiles mysteriously" />
                    <Label Text="  &#x2022; Sleeps sitting up" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}"
                           WidthRequest="180"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Banana Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="Watch this monkey eat a giant banana." />
                    <Label Text="  &#x2022; More fun than a barrel of monkeys" />
                    <Label Text="  &#x2022; Banana not included" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}"
                           WidthRequest="240"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame WidthRequest="300"
                   HeightRequest="480">

                <FlexLayout Direction="Column">
                    <Label Text="Face-Palm Monkey"
                           Style="{StaticResource headerLabel}" />
                    <Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
                    <Label Text="  &#x2022; Cynical but not unfriendly" />
                    <Label Text="  &#x2022; Seven varieties of grimaces" />
                    <Label Text="  &#x2022; Doesn't laugh at your jokes" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}"
                           WidthRequest="180"
                           HeightRequest="180" />
                    <Label FlexLayout.Grow="1" />
                    <Button />
                </FlexLayout>
            </Frame>
        </FlexLayout>
    </ScrollView>
</ContentPage>

Image の暗黙的なスタイルには、Flexlayout の 2 つのアタッチされたバインド可能なプロパティの設定が含まれています。

<Style TargetType="Image">
    <Setter Property="FlexLayout.Order" Value="-1" />
    <Setter Property="FlexLayout.AlignSelf" Value="Center" />
</Style>

Order を –1 に設定すると、子コレクション内での位置に関係なく、入れ子になった FlexLayout ビューのそれぞれで最初に Image 要素が表示されます。 CenterAlignSelf プロパティにより、ImageFlexLayout 内で中央に配置されます。 これにより、既定値が StretchAlignItems プロパティの設定がオーバーライドされます。つまり、LabelButton の子が FlexLayout の全幅に拡張されます。

3 つの FlexLayout ビューそれぞれで、空白の LabelButton より前に表示されますが、Grow の設定は 1 です。 つまり、余分な縦方向スペースのすべてがこの空白 Label に割り当てられ、実質的に Button は下にプッシュされます。

バインド可能なプロパティの詳細

ここまで FlexLayout の一般的なアプリケーションを見てきたので、FlexLayout のプロパティの詳細を確認していきます。 FlexLayout は、FlexLayout 自体を設定する 6 つのバインド可能なプロパティを、コードまたは XAML で定義して、方向と配置を制御します。 (これらのプロパティの 1 つである Position は、この記事では取り上げません)。

サンプルの [Experiment] ページを使用して、残りの 5 つのバインド可能なプロパティを試すことができます。 このページでは、FlexLayout に対して子を追加および削除したり、5 つのバインド可能なプロパティの組み合わせを設定したりすることができます。 FlexLayout のすべての子は、さまざまな色やサイズの Label ビューであり、Text プロパティは Children コレクション内の位置に対応する数値に設定されます。

プログラムが起動すると、5 つの Picker ビューに 5 つの FlexLayout プロパティの既定値が表示されます。 FlexLayout には、画面の下方に向かって、3 つの子が含まれています。

[Experiment] ページ: 既定値

Label ビューの背景は灰色で、FlexLayout 内で Label に割り当てられたスペースが表示されます。 FlexLayout 自体の背景はアリス ブルーです。 左右に余白がある場合を除き、ページの下部全体を占めています。

Direction プロパティ

Direction プロパティは、4 個のメンバーを持つ FlexDirection 列挙型です。

  • Column
  • ColumnReverse (または XAML では "column-reverse")
  • Row (既定値)
  • RowReverse (または XAML では "row-reverse")

XAML では、小文字、大文字、または大小混在の列挙メンバー名を使用して、このプロパティの値を指定するか、CSS インジケーターと同じかっこで囲まれた 2 つの追加文字列を使用できます。 ("column-reverse" と "row-reverse" の文字列は、XAML パーサーによって使用される FlexDirectionTypeConverter クラスで定義されます)。

(左から右へ) Row 方向、Column 方向、ColumnReverse 方向が表示された [実験] ページは次のとおりです。

[Experiment] ページ: 方向

Reverse オプションの場合、項目は右または下部から始まります。

Wrap プロパティ

Wrap プロパティは、3 個のメンバーを持つ FlexWrap 列挙型です。

  • NoWrap (既定値)
  • Wrap
  • Reverse (または XAML では "wrap-reverse")

次の画面には、左から右に、12 個の子に対する NoWrapWrapReverse オプションが示されています。

[Experiment] ページ: 折り返し

Wrap プロパティが NoWrap に設定されていて、(このプログラムのように) 主軸に制約があり、すべての子を収めるのに十分な幅または高さが主軸にない場合、FlexLayout は iOS のスクリーンショットに示すように、項目を小さくしようとします。 アタッチされたバインド可能な Shrink プロパティを使用して、項目の縮小を制御できます。

JustifyContent プロパティ

JustifyContent プロパティは、6 個のメンバーを持つ FlexJustify 列挙型です。

  • Start (または XAML では "flex-start")、既定値
  • Center
  • End (または XAML では "flex-end")
  • SpaceBetween (または XAML では "space-between")
  • SpaceAround (または XAML では "space-around")
  • SpaceEvenly

このプロパティは、項目を主軸 (この例では横軸) に配置する方法を指定します。

[Experiment] ページ: コンテンツの両端揃え

3 つのスクリーンショットすべてで、Wrap プロパティは Wrap に設定されています。 既定の Start は、前の Android のスクリーンショットに示されています。 ここの iOS のスクリーンショットでは、すべての項目が中央に移動される Center オプションが示されています。 Space という単語で始まる他の 3 つのオプションは、項目に占有されていない余分なスペースを割り当てます。 SpaceBetween は項目間に均等にスペースを割り当てます。SpaceAround は各項目の周囲に等しいスペースを配置し、SpaceEvenly は各項目の間、行の最初の項目の前、行の最後の項目の後に等しいスペースを配置します。

AlignItems プロパティ

AlignItems プロパティは、4 個のメンバーを持つ FlexAlignItems 列挙型です。

  • Stretch (既定値)
  • Center
  • Start (または XAML では "flex-start")
  • End (または XAML では "flex-end")

これは、子が交差軸にどのように配置されるかを示す 2 つのプロパティのうちの 1 つです (もう 1 つは AlignContent)。 各行内では、次の 3 つのスクリーンショットに示すように、子が (前のスクリーンショットに示されているように) 拡張されるか、各項目の先頭、中央、末尾で揃えられます。

[Experiment] ページ: 項目の配置

iOS のスクリーンショットでは、すべての子の上部が揃っています。 Android のスクリーンショットでは、項目は最も高さがある子に基づいて縦方向に中央揃えされています。 UWP のスクリーンショットでは、すべての項目の下部が揃っています。

個々の項目に対して、AlignItems の設定は、アタッチされたバインド可能な AlignSelf プロパティ内でオーバーライドできます。

AlignContent プロパティ

AlignContent プロパティは 7 個のメンバーを持つ FlexAlignContent 列挙型です。

  • Stretch (既定値)
  • Center
  • Start (または XAML では "flex-start")
  • End (または XAML では "flex-end")
  • SpaceBetween (または XAML では "space-between")
  • SpaceAround (または XAML では "space-around")
  • SpaceEvenly

AlignItems と同様に、この AlignContent プロパティも子を交差軸上に揃えて配置しますが、行または列全体にも影響します。

[Experiment] ページ: コンテンツの配置

iOS のスクリーンショットでは、両方の行が上部に、Android のスクリーンショットでは中央に、UWP のスクリーンショットでは下部に配置されています。 行は、さまざまな方法で配置することができます。

[Experiment] ページ: コンテンツの配置 2

行または列が 1 つしかない場合、AlignContent は効果を発揮しません。

アタッチされたバインド可能なプロパティの詳細

FlexLayout は 5 つのアタッチされたバインド可能なプロパティを定義します。 これらのプロパティは、FlexLayout の子に設定され、その特定の子にのみ関連します。

AlignSelf プロパティ

アタッチされたバインド可能な AlignSelf プロパティは、5 個のメンバーを持つ FlexAlignSelf 列挙型です。

  • Auto (既定値)
  • Stretch
  • Center
  • Start (または XAML では "flex-start")
  • End (または XAML では "flex-end")

FlexLayout の個々の子では、このプロパティ設定は、FlexLayout 自体に設定された AlignItems プロパティをオーバーライドします。 規定設定の Auto は、AlignItems 設定を使用することを意味します。

label (または example) という名前の Label 要素の場合は、次のようにコードで AlignSelf プロパティを設定できます。

FlexLayout.SetAlignSelf(label, FlexAlignSelf.Center);

LabelFlexLayout の親への参照がないことに注意してください。 XAML では、次のようにプロパティを設定します。

<Label ... FlexLayout.AlignSelf="Center" ... />

Order プロパティ

Order プロパティは int 型です。 既定値は0です。

Order プロパティを使用すると、FlexLayout の子を配置する順序を変更できます。 通常、FlexLayout の子は Children コレクションに表示される順序と同じ順序で配置されます。 この順序をオーバーライドするには、1 つ以上の子のアタッチされたバインド可能な Order プロパティを 0 以外の整数値に設定します。 次に、FlexLayout は、子それぞれの Order プロパティの設定に基づいて子を配置しますが、Order 設定が同じ子は、Children コレクションに表示される順序で配置されます。

Basis プロパティ

アタッチされたバインド可能な Basis プロパティは、主軸にある FlexLayout の子に割り当てられるスペースの量を示します。 Basis プロパティで指定されるサイズは、FlexLayout の親の主軸方向のサイズです。 したがって、Basis は、子が行に配置されたときの子の幅、または子が列に配置されたときの高さを示します。

Basis プロパティは FlexBasis 型で、構造体です。 サイズはデバイスに依存しない単位か、FlexLayout のサイズに対するパーセンテージで指定できます。 Basis プロパティの既定値は静的プロパティ FlexBasis.Auto であり、これは、指定された子の幅または高さが使用されることを意味します。

コードでは、label という名前の LabelBasis プロパティを、次のように、デバイスに依存しない 40 個の単位に設定できます。

FlexLayout.SetBasis(label, new FlexBasis(40, false));

FlexBasis コンストラクターの 2 つ目の引数には isRelative という名前が付けられており、サイズが相対 (true) か絶対 (false) かを示します。 引数の既定値は false で、次のコードを使用することもできます。

FlexLayout.SetBasis(label, new FlexBasis(40));

float から FlexBasis への暗黙的な変換が定義されているため、さらに簡略化できます。

FlexLayout.SetBasis(label, 40);

次のように、FlexLayout の親のサイズを 25% に設定できます。

FlexLayout.SetBasis(label, new FlexBasis(0.25f, true));

この小数値は 0 ~ 1 の範囲になければなりません。

XAML では、デバイスに依存しない単位でサイズに数値を使用できます。

<Label ... FlexLayout.Basis="40" ... />

または、0% から 100% の範囲でパーセンテージを指定できます。

<Label ... FlexLayout.Basis="25%" ... />

サンプルの [Basis Experiment] ページでは、Basis プロパティを試すことができます。 このページには、背景色と前景色が交互に配置された 5 つの Label 要素のラップ列が表示されます。 2 つの Slider 要素を使用すると、2 つ目と 4 つ目の LabelBasis の値を指定できます。

[Basis Experiment] ページ

左側の iOS のスクリーンショットは、デバイスに依存しない単位で高さが指定されている 2 つの Label 要素を示しています。 Android の画面は、FlexLayout の全高の何分の 1 かの高さが指定されたことを示しています。 Basis が 100% に設定されている場合、子は FlexLayout の高さであり、次の列にラップされ、列の高さ全体を占有します。UWP のスクリーンショットのように、5 つの子が 1 行に配置されているかのように見えますが、実際には 5 列に配置されています。

Grow プロパティ

アタッチされたバインド可能な Grow プロパティは int 型です。 既定値は 0 で、この値は 0 以上である必要があります。

Grow プロパティは、Wrap プロパティが NoWrap に設定されていて、子の行の全幅が FlexLayout の幅より小さい場合、または子の列の高さが FlexLayout よりも短い場合に役割を果たします。 Grow プロパティは、子の残りのスペースを割り当てる方法を示します。

[Grow Experiment] (実験の拡張) ページでは、色が交互の 5 つの Label 要素が列に配置され、2 つの Slider 要素を使用して 2 つ目と 4 つ目の LabelGrow プロパティを調整できます。 左端の iOS のスクリーンショットは、既定値の 0 に設定された Grow プロパティを示しています。

[Grow Experiment] ページ

いずれかの子に正の Grow 値を指定すると、Android のスクリーンショットに示すように、その子が残りのすべてのスペースを占有します。 このスペースは、2 つ以上の子に割り当てることもできます。 UWP のスクリーンショットでは、2 つ目の LabelGrow プロパティが 0.5 に設定され、4 つ目の LabelGrow プロパティが 1.5 に設定されています。これにより、4 つ目の Label プロパティに割り当てられる残りのスペースが、2 つ目の Label の 3 倍になります。

子ビューでそのスペースを使用する方法は、子の型によって異なります。 Label の場合、テキストは HorizontalTextAlignmentVerticalTextAlignment のプロパティを使用して、Label の全スペース内に配置されます。

Shrink プロパティ

アタッチされたバインド可能な Shrink プロパティは int 型です。 既定値は 1 で、この値は 0 以上である必要があります。

Shrink プロパティは、Wrap プロパティが NoWrap に設定され、子の行の集計幅が FlexLayout の幅より大きい場合、または子の 1 つの列の集計高さが FlexLayout の高さよりも大きい場合に、役割を果たします。 通常、FlexLayout ではこれらの子はサイズを制限して表示されます。 Shrink プロパティは、フル サイズで表示する際にどの子が優先されているかを示すことができます。

[Shrink Experiment] (実験の縮小) ページでは、5 つの Label 子の 1 つの行が FlexLayout の幅よりも大きいスペースを必要としている FlexLayout が作成されます。 左側の iOS のスクリーンショットでは、すべての Label 要素に既定値の 1 が設定されています。

[Shrink Experiment] ページ

Android のスクリーンショットでは、2 つ目の LabelShrink 値が 0 に設定され、Label が全幅で表示されます。 また、4 つ目の Label には 1 より大きい Shrink 値が設定され、縮小されています。 UWP のスクリーンショットでは、両方の Label 要素の Shrink 値に 0 が設定されているため、可能であれば、フルサイズで表示することができます。

GrowShrink の両方の値を設定することで、集計子サイズが FlexLayout のサイズより小さい場合や大きい場合に対応することができます。

FlexLayout を使用した CSS スタイル

FlexLayout に関して、Xamarin.Forms 3.0 で導入された CSS スタイル機能を使用することができます。 [CSS Catalog Items] ページは、[Catalog Items] ページのレイアウトを複製しますが、多くのスタイルは CSS スタイル シートを使用します。

[CSS Catalog Items] ページ

元の CatalogItemsPage.xaml ファイルの Resources セクションには、15 個の Setter オブジェクトを含む 5 つの Style 定義があります。 CssCatalogItemsPage.xaml ファイルでは、4 つの Setter オブジェクトのみを含む 2 つの Style 定義に縮小されています。 これらのスタイルは、Xamarin.Forms CSS スタイル機能が現在サポートしていないプロパティの CSS スタイル シートを補完します。

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:FlexLayoutDemos"
             x:Class="FlexLayoutDemos.CssCatalogItemsPage"
             Title="CSS Catalog Items">
    <ContentPage.Resources>
        <StyleSheet Source="CatalogItemsStyles.css" />

        <Style TargetType="Frame">
            <Setter Property="BorderColor" Value="Blue" />
            <Setter Property="CornerRadius" Value="15" />
        </Style>

        <Style TargetType="Button">
            <Setter Property="Text" Value="LEARN MORE" />
            <Setter Property="BorderRadius" Value="20" />
        </Style>
    </ContentPage.Resources>

    <ScrollView Orientation="Both">
        <FlexLayout>
            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Seated Monkey" StyleClass="header" />
                    <Label Text="This monkey is laid back and relaxed, and likes to watch the world go by." />
                    <Label Text="  &#x2022; Doesn't make a lot of noise" />
                    <Label Text="  &#x2022; Often smiles mysteriously" />
                    <Label Text="  &#x2022; Sleeps sitting up" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.SeatedMonkey.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Banana Monkey" StyleClass="header" />
                    <Label Text="Watch this monkey eat a giant banana." />
                    <Label Text="  &#x2022; More fun than a barrel of monkeys" />
                    <Label Text="  &#x2022; Banana not included" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.Banana.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>

            <Frame>
                <FlexLayout Direction="Column">
                    <Label Text="Face-Palm Monkey" StyleClass="header" />
                    <Label Text="This monkey reacts appropriately to ridiculous assertions and actions." />
                    <Label Text="  &#x2022; Cynical but not unfriendly" />
                    <Label Text="  &#x2022; Seven varieties of grimaces" />
                    <Label Text="  &#x2022; Doesn't laugh at your jokes" />
                    <Image Source="{local:ImageResource FlexLayoutDemos.Images.FacePalm.jpg}" />
                    <Label StyleClass="empty" />
                    <Button />
                </FlexLayout>
            </Frame>
        </FlexLayout>
    </ScrollView>
</ContentPage>

CSS スタイル シートは、Resources セクションの最初の行で参照されます。

<StyleSheet Source="CatalogItemsStyles.css" />

また、3 つの項目のそれぞれにある 2 つの要素に StyleClass 設定が含まれていることにも注意してください。

<Label Text="Seated Monkey" StyleClass="header" />
···
<Label StyleClass="empty" />

これらは、CatalogItemsStyles.css スタイル シートのセレクターを参照します。

frame {
    width: 300;
    height: 480;
    background-color: lightyellow;
    margin: 10;
}

label {
    margin: 4 0;
}

label.header {
    margin: 8 0;
    font-size: large;
    color: blue;
}

label.empty {
    flex-grow: 1;
}

image {
    height: 180;
    order: -1;
    align-self: center;
}

button {
    font-size: large;
    color: white;
    background-color: green;
}

ここでは、アタッチされたバインド可能な FlexLayout プロパティをいくつか参照します。 label.empty セレクターには、flex-grow 属性が表示されます。これにより、空の Label のスタイルが設定され、空白スペースが Button の上に指定されます。 image セレクターには order 属性と align-self 属性が含まれ、どちらもアタッチされたバインド可能な FlexLayout プロパティに対応します。

FlexLayout でプロパティを直接設定できることと、アタッチされたバインド可能なプロパティを FlexLayout の子で設定できることを確認してきました。 または、従来の XAML ベースのスタイルまたは CSS スタイルを使用して、これらのプロパティを間接的に設定することもできます。 重要なのは、これらのプロパティを知り、理解することです。 これらのプロパティにより、FlexLayout は本当に柔軟になります。

Xamarin University を使用した FlexLayout

Xamarin.Forms 3.0 Flex Layout ビデオ