Xamarin.Form的LayoutOptions有什么区别,特别是Fill和Expand?

时间:2014-08-16 08:56:42

标签: c# layout view xamarin xamarin.forms

在Xamarin.Forms中,每个View都有两个属性HorizontalOptionsVerticalOptions。两者都是LayoutOptions类型,可以具有以下值之一:

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

显然它控制父视图上视图的对齐方式。但每个选项的行为究竟如何呢? Fill和后缀Expand之间有什么区别?

3 个答案:

答案 0 :(得分:315)

简短回答

StartCenterEndFill定义视图在其空间内的对齐

Expand定义是否占用更多空间(如果可用)。

理论

结构LayoutOptions控制两种不同的行为:

  1. 对齐: 视图如何在父视图中对齐?

    • Start:对于垂直对齐,视图会移到顶部。对于水平对齐,这通常是左侧。 (但请注意,在具有从右到左语言设置的设备上,这是另一种方式,即右对齐。)
    • Center:视图居中。
    • End:通常视图底部或右侧对齐。 (从右到左的语言,当然,左对齐。)
    • Fill:此对齐略有不同。视图将在父视图的整个大小上延伸。

    但是,如果父母不比其子女大,则不会发现这些对齐之间存在任何差异。对齐仅对具有额外可用空间的父视图有用。

  2. 扩展: 如果可用,该元素是否会占用更多空间?

    • 后缀Expand:如果父视图大于其所有子视图的组合大小,即可获得额外空间,则该空间在具有该后缀的子视图中成比例。那些孩子将“占据”他们的空间,但不一定“填补”它。我们将在下面的示例中查看此行为。
    • 无后缀:没有Expand后缀的孩子将无法获得额外空间,即使有更多空间可供使用。

    同样,如果父视图不大于其子​​视图,则扩展后缀也不会产生任何差异。

  3. 实施例

    让我们看看以下示例,看看所有八个布局选项之间的区别。

    该应用包含一个深灰色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,
            });
        }
    }
    

    以下屏幕截图显示了单击八个按钮时的结果。我们做了以下观察:

    • 只要父stackLayout紧张(页面不Fill),每个Button的垂直布局选项就可以忽略不计。
    • 纵向布局选项仅在stackLayout较大(例如,通过Fill路线)并且各个按钮具有Expand后缀时才重要。
    • Expand后缀的所有按钮中,额外的空间通常是按比例的。为了更清楚地看到这一点,我们在每两个相邻按钮之间添加了黄色水平线。
    • 空间大于要求高度的按钮不一定“填充”它。在这种情况下,实际行为由它们的对齐控制。例如。它们要么在它们的空间的顶部,中心或按钮上对齐,要么完全填满。
    • 所有按钮都跨越整个布局宽度,因为我们只修改VerticalOptions

    Screenshots

    Here you find the corresponding high-resolution screenshots.

答案 1 :(得分:14)

当前版本的Xamarin.Forms中存在一些错误;也许它已经有一段时间了。

CenterAndExpand通常不会扩展,并且解决它可能会造成混淆。

例如,如果您将StackLayout设置为CenterAndExpand,那么您将一个标签设置为CenterAndExpand,您希望标签的宽度为{StackLayout 1}}。不。它不会扩大。您必须将StackLayout设置为" FillAndExpand"要使嵌套的Label对象扩展到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" />

答案 2 :(得分: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>

如您所见,这是一个非常简单的StackLayout,其中带有Label。对于下面的每个图像,我都保持StackLayout不变,只是更改了Entry的水平和垂直选项,并更改了文本以显示所选的选项,因此您可以看到Entry如何移动和调整大小。

Start vs StartAndExpand 这是用于开始的代码:

<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 vs FillAndExpand

我还建议您查看Microsoft documentation,以了解更多其他详细信息。值得注意的是“扩展仅由StackLayout使用”。