web-dev-qa-db-ja.com

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

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の違いは何ですか?

157
Falko

短い答え

StartCenterEnd、およびFillは、そのスペース内のビューの位置合わせを定義します

Expandは、使用可能な場合にそれがより多くのスペースを占有するかどうかを定義します

理論

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

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

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

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

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

    • 接尾辞Expand:親ビューがそのすべての子の合計サイズよりも大きい場合、つまり追加のスペースが利用可能な場合、スペースはその接尾辞を持つ子ビューの間で比例します。それらの子供は自分のスペースを「占有」しますが、必ずしも「埋める」とは限りません。次の例で、この動作を確認します。
    • 接尾辞なし:Expand接尾辞のない子は、使用可能なスペースがさらにある場合でも、追加のスペースを取得しません。

    繰り返しますが、親ビューがその子より大きくない場合、展開接尾辞も同様に違いはありません。

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

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

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

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のみを変更するため、すべてのボタンはレイアウトの幅全体に広がります。

Screenshots

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

316
Falko

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

CenterAndExpandは一般に展開されず、回避するのは混乱する可能性があります。

たとえば、StackLayoutCenterAndExpandに設定されている場合、CenterAndExpandに設定されたラベルをその中に配置すると、StackLayoutの全幅のラベルが期待されます。いや。拡大しません。 StackLayoutを "FillAndExpand"に設定して、ネストされたLabelオブジェクトをStackLayoutの全幅に拡張し、HorizontalTextAlignment="Center"を使用して、Labelにオブジェクトとしてではなく、テキストを中央揃えにする必要があります。私の経験では、親とネストされた子の両方をFillAndExpandに設定する必要があります。

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