Xamarin.FormのLayoutOptions、特にFillとExpandの違いは何ですか?


170

Xamarin.Forms Viewでは、すべてにとの2つのプロパティがHorizontalOptionsありVerticalOptionsます。どちらもタイプでLayoutOptionsあり、次のいずれかの値をとることができます。

  • LayoutOptions.Start
  • LayoutOptions.Center
  • LayoutOptions.End
  • LayoutOptions.Fill
  • LayoutOptions.StartAndExpand
  • LayoutOptions.CenterAndExpand
  • LayoutOptions.EndAndExpand
  • LayoutOptions.FillAndExpand

どうやらそれは親ビュー上のビューの配置を制御します。しかし、個々のオプションの動作はどのくらい正確ですか?Fillとのサフィックスの違いは何Expandですか?

回答:


335

短い答え

StartCenterEndおよびFillビューの定義その空間内での位置合わせを

Expand可能な場合、より多くのスペースを占有するかどうかを定義します。

理論

この構造LayoutOptionsは、2つの異なる動作を制御します。

  1. 配置: ビューは親ビュー内でどのように配置されますか?

    • Start:垂直方向の配置では、ビューが上部に移動します。水平配置の場合、これは通常左側です。(ただし、右から左への言語設定を備えたデバイスでは、これは逆になります。つまり、右揃えになります。)
    • Center:ビューが中央に配置されます。
    • End:通常、ビューは下または右揃えです。(もちろん、右から左への言語では、左揃えになります。)
    • Fill:この配置は少し異なります。ビューは、親ビューのフルサイズに拡大されます。

    ただし、親が子よりも大きくない場合は、これらの配置の違いに気付くことはありません。配置は、追加のスペースが利用可能な親ビューに対してのみ重要です。

  2. 拡張: 可能な場合、要素はより多くのスペースを占有しますか?

    • サフィックス Expand:親ビューがそのすべての子の合計サイズよりも大きい場合、つまり追加のスペースが利用可能な場合、スペースはその接尾辞を持つ子ビュー間で配分されます。それらの子供たちは自分のスペースを「占有」しますが、必ずしも「満たす」必要はありません。以下の例で、この動作を確認します。
    • 接尾辞なし:Expand接尾辞のない子は、さらに多くのスペースが利用可能であっても、追加のスペースを取得しません。

    この場合も、親ビューがその子よりも大きくない場合は、拡張サフィックスによっても違いはありません。

次の例を見て、8つのレイアウトオプションすべての違いを見てみましょう。

アプリにはダークグレーが含まれており、StackLayout8つのネストされた白いボタンがあり、それぞれに垂直レイアウトオプションのラベルが付いています。ボタンの1つをクリックすると、垂直レイアウトオプションがスタックレイアウトに割り当てられます。このようにして、異なるレイアウトオプションを使用して、ビューと親の相互作用を簡単にテストできます。

(最後の数行のコードは、黄色のボックスを追加します。これについては、すぐに戻ってきます。)

public static class App
{
    static readonly StackLayout stackLayout = new StackLayout {
        BackgroundColor = Color.Gray,
        VerticalOptions = LayoutOptions.Start,
        Spacing = 2,
        Padding = 2,
    };

    public static Page GetMainPage()
    {
        AddButton("Start", LayoutOptions.Start);
        AddButton("Center", LayoutOptions.Center);
        AddButton("End", LayoutOptions.End);
        AddButton("Fill", LayoutOptions.Fill);
        AddButton("StartAndExpand", LayoutOptions.StartAndExpand);
        AddButton("CenterAndExpand", LayoutOptions.CenterAndExpand);
        AddButton("EndAndExpand", LayoutOptions.EndAndExpand);
        AddButton("FillAndExpand", LayoutOptions.FillAndExpand);

        return new NavigationPage(new ContentPage {
            Content = stackLayout,
        });
    }

    static void AddButton(string text, LayoutOptions verticalOptions)
    {
        stackLayout.Children.Add(new Button {
            Text = text,
            BackgroundColor = Color.White,
            VerticalOptions = verticalOptions,
            HeightRequest = 20,
            Command = new Command(() => {
                stackLayout.VerticalOptions = verticalOptions;
                (stackLayout.ParentView as Page).Title = "StackLayout: " + text;
            }),
        });
        stackLayout.Children.Add(new BoxView {
            HeightRequest = 1,
            Color = Color.Yellow,
        });
    }
}

次のスクリーンショットは、8つのボタンのそれぞれをクリックしたときの結果を示しています。以下の観察を行います。

  • stackLayoutがタイト(Fillページではない)である限り、それぞれの垂直レイアウトオプションButtonは無視できます。
  • 垂直方向のレイアウトオプションstackLayoutは、が大きい場合(たとえば、Fill配置を介して)、個々のボタンにExpandサフィックスがある場合にのみ重要です。
  • 追加のスペースは、最終的にすべてのボタンにExpandサフィックスが付いた比率になります。これをより明確に表示するために、隣接する2つのボタンの間に黄色の水平線を追加しました。
  • 要求された高さよりも多くのスペースがあるボタンは、必ずしもそれを「埋める」とは限りません。この場合、実際の動作はそれらの配置によって制御されます。たとえば、スペースの上部、中央、またはボタンに配置するか、完全に埋めます。
  • を変更するだけなので、すべてのボタンはレイアウトの幅全体に広がりVerticalOptionsます。

スクリーンショット

ここに、対応する高解像度のスクリーンショットがあります。


6
画像は[[midfing]]のように見えます、笑。冗談で本当に助かりました
Joy Rex

1
@JoyRex:まあ、多分このバージョンは少し混乱が少ないです。;)
Falko、2015

2
上記の出力と混同しています。startとstartAndExpandはどちらも同じ出力です。これらの違いは何ですか?可能な場合は、説明を与えることができます。..
ランジット・クマールに

1
FillAndExpandあなたが欲しいもの、99%の時間
Stephane Delcroix

1
@RanjithKumar彼らは同じです。StackLayoutが別の親にネストされていた場合、FillAndExpandは違いを生む可能性があり、その親内で拡張されます。
Miha Markic 2017

16

Xamarin.Formsの現在のバージョンには少しバグがあります。多分それはしばらくありました。

CenterAndExpand 通常は拡張されず、回避すると混乱する可能性があります。

たとえば、がにStackLayout設定されている場合は、CenterAndExpandその中にも設定されているラベルを内側に配置するCenterAndExpandと、の全幅のラベルが期待されますStackLayout。いいえ。拡大しません。ネストされたLabelオブジェクトをの全幅に拡大するには、StackLayoutを " FillAndExpand" に設定してからStackLayout、Labelに、それ自体をオブジェクトとしてではなく、テキストの中央に配置するように指示する必要がありますHorizontalTextAlignment="Center"。私の経験では、FillAndExpand実際に収まるように拡張したい場合は、親とネストされた子の両方を設定する必要があります。

        <StackLayout HorizontalOptions="FillAndExpand"
                     Orientation="Vertical"
                     WidthRequest="300">
            <Label BackgroundColor="{StaticResource TileAlerts}"
                   HorizontalOptions="FillAndExpand"
                   Style="{StaticResource LabelStyleReversedLrg}"
                   HorizontalTextAlignment="Center"
                   Text="Alerts" />

3
「... StackLayoutの幅いっぱいのラベルが必要です。」この仮定は正しくありません。ExpandStackLayoutの子にのみ使用されます。したがって、StackLayoutがルートである場合、または別のStackLayoutにExpandない場合、影響はありません。代わりに、Fill以外のオプションは、サイズ変更の「折り返しコンテンツ」として機能します。
therealjohn 16

さらに、展開は、StackLayoutと同じ方向のLayoutOptionsに対してのみ機能します。この場合、レイアウトは「垂直」ですが、問題のオプションは水平(反対)です。
therealjohn

「AndExpand」という用語はあいまいです。「可能な限り拡大」または「必要なだけ拡大」と解釈できます。Microsoftは、用語を「CenterAndExpandToParent」や「CenterAndExpandAsNeeded」などのわかりやすいものに変更する必要があると思います
technoman23

1

Falkoは良い説明をしましたが、私は別のビジュアルとこれらのタグがxamlでどのように機能するかを追加したかったので、ほとんどの場合これを使用します。表示結果をテストするための簡単なプロジェクトを作成しました。メインページのXamlは次のとおりです。

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Alignments.MainPage"
             BackgroundColor="White">


    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" BackgroundColor="LightGray" Padding="1" Margin="30">
        <Label Text="Vert: EndAndExpand, Horz: EndAndExpand" VerticalOptions="EndAndExpand" HorizontalOptions="EndAndExpand" BackgroundColor="White"/>
    </StackLayout>


</ContentPage>

ご覧のとおり、内部にLabelがある非常に単純なStackLayoutです。以下の各画像について、StackLayoutを同じに保ち、項目の水平および垂直オプションを変更し、選択したオプションを表示するようにテキストを変更したので、項目がどのように移動してサイズ変更されるかを確認できます。

StartとStartAndExpand Startに使用されるコードは次のとおりです。

<Label Text="Vert: Start, Horz: Start" VerticalOptions="Start" HorizontalOptions="Start" BackgroundColor="White"/>

そして、StartAndExpandに使用されるコード:

<Label Text="Vert: StartAndExpand, Horz: StartAndExpand" VerticalOptions="StartAndExpand" HorizontalOptions="StartAndExpand" BackgroundColor="White"/>

ご覧のとおり、StartAndExpandオプションで使用されるテキストが多いこと以外は視覚的に違いはありません。これは私のSamsung A30物理デバイスでテストされました。これらはデバイスによって表示が異なる場合がありますが、ここにあるすべての画像は、Xamarinにいくつかのバグがあることを示しています。残りについては、スクリーンショットのみを表示します。それらは自明です。

End vs EndAndExpand

Center vs CenterAndExpand

FillとFillAndExpand

追加の詳細については、Microsoftのドキュメントを参照することもお勧めします。注目すべきは、「ExpansionはStackLayoutによってのみ使用される」ことです。


素晴らしい視覚化。しかし、これがXamarinのバグを表示する理由がわかりません。紛らわしいのは、ラベルが白い背景(この例では灰色の領域)よりも多くのスペースを占める可能性があることです。したがって、「Vert Center」ラベルは、ページ全体ではなく、占有するスペースの中央に配置されます。どうやら、ほぼ6年経った後も、このトピックは以前よりも混乱しています。
ファルコ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.