【问题标题】:What is the difference between Xamarin.Form's LayoutOptions, especially Fill and Expand?Xamarin.Form 的 LayoutOptions 有什么区别,尤其是 Fill 和 Expand?
【发布时间】:2014-10-09 21:42:06
【问题描述】:

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

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

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

【问题讨论】:

    标签: c# layout view xamarin xamarin.forms


    【解决方案1】:

    简答

    Start、Center、End 和 Fill 定义视图的在其空间内的对齐方式。

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

    理论

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

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

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

      但是,如果父级不大于其子​​级,您将不会注意到这些对齐方式之间的任何差异。对齐只对有额外可用空间的父视图很重要。

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

      • 后缀Expand:如果父视图大于其所有子视图的组合大小,即有额外空间可用,则空间在具有该后缀的子视图之间按比例分配。那些孩子会“占据”他们的空间,但不一定会“填满”它。我们将在下面的示例中了解这种行为。
      • 无后缀:没有Expand 后缀的孩子不会获得额外的空间,即使有更多可用空间。

      同样,如果父视图不大于其子​​视图,扩展后缀也没有任何区别。

    示例

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

    该应用程序包含一个深灰色的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。

    Here you find the corresponding high-resolution screenshots.

    【讨论】:

    • 图像看起来像 [[midfing]] ,哈哈。开个玩笑真的很有帮助
    • @JoyRex:嗯,也许this version 不那么令人困惑。 ;)
    • 我对上面的输出感到困惑。 start 和 startAndExpand 都是相同的输出。这些有什么区别?如果可能的话,你能解释一下吗..
    • FillAndExpand 是你想要的,99% 的时间
    • @RanjithKumar 他们是一样的。它 StackLayout 嵌套在另一个父级中,然后它的 FillAndExpand 可能会有所作为 - 它会在 其 父级中扩展。
    【解决方案2】:

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

    CenterAndExpand 通常不会扩展,解决它可能会令人困惑。

    例如,如果您将StackLayout 设置为CenterAndExpand,那么您在其中放置一个标签,该标签也设置为CenterAndExpand,您会期望标签是StackLayout 的全宽。没有。它不会扩大。您必须将StackLayout 设置为“FillAndExpand”以使嵌套的标签对象扩展到StackLayout 的整个宽度,然后告诉标签将文本居中,而不是将其本身作为对象,使用@987654329 @。根据我的经验,如果你真的想确保它扩展以适应,你需要将父级和嵌套子级都设置为 FillAndExpand。

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

    【讨论】:

    • "...您会期望一个标签是 StackLayout 的全宽。"这个假设是不正确的。 Expand 仅用于 StackLayout 的子级。因此,如果您的 StackLayout 是根,或者不在另一个 StackLayout 中,Expand 没有影响。相反,除了 Fill 之外的任何选项都将充当大小的“包装内容”,这就是您所看到的。
    • 另外,扩展只适用于与StackLayout方向相同的LayoutOptions。在这种情况下,布局是“垂直”,但有问题的选项是水平(相反)。
    • “AndExpand”一词含糊不清。它可以解释为“尽可能多地扩展”或“仅按需扩展”。我认为微软应该将这些术语更改为不那么令人困惑的内容,例如“CenterAndExpandToParent”或“CenterAndExpandAsNeeded”
    【解决方案3】:

    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 如何移动和调整大小。

    下面是用于启动的代码:

    <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 选项中使用了更多文本外,视觉上没有区别。这是在我的三星 A30 物理设备上测试的。这些可能在不同的设备上显示不同,但我认为这里的所有图像共同表明 Xamarin 中存在一些错误。其余的我只展示截图,我认为它们是不言自明的。

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

    【讨论】:

    • 漂亮的可视化。但我不明白为什么这应该在 Xamarin 中显示错误。可能令人困惑的是,标签可能比它们的白色背景(我的例子中的灰色区域)占据更多的空间。因此,“垂直中心”标签在其占据的空间内居中 - 而不是在整个页面内。显然,在将近六年后,这个话题仍然像以前一样令人困惑。
    猜你喜欢
    • 1970-01-01
    • 2012-04-25
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 2019-03-08
    • 2010-09-05
    相关资源
    最近更新 更多