【问题标题】:How can I change a <StackLayout> <Grid> screen to use <RelativeLayout>?如何更改 <StackLayout> <Grid> 屏幕以使用 <RelativeLayout>?
【发布时间】:2017-08-11 17:15:42
【问题描述】:

我有这段代码,目前是 和 的组合

我想改用相对布局,但还没有看到太多这样的例子。将不胜感激有关如何实现这一点的任何建议。

关于 XAML 的一些要点。

  • emptyGrid 或 phraseGrid 出现在屏幕上
  • buttonGrid 或 tapGrid 出现在屏幕上
  • 按钮的垂直中心和点击标签应该在同一位置。这样当按钮未显示时,点击标签会出现在与按钮相同的垂直按钮上。
  • 框架出现在标签页内

我意识到这不仅仅是一个简单的问题,但我相信其他人会对此感兴趣。由于答案可能非常复杂,因此我将在几天内为此开放 250 点赏金。

    <Grid x:Name="emptyGrid" Grid.Row="1" Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <StackLayout Padding="10,0,10,0" HorizontalOptions="Center" VerticalOptions="Center">
            <Label x:Name="emptyLabel" FontSize="18" XAlign="Center" TextColor="Gray" />
        </StackLayout>
        <Button x:Name="resetButton" Text="Reset points?" TextColor="White" FontAttributes="Bold" FontSize="20" HeightRequest="60" BackgroundColor="#E19A3F" HorizontalOptions="FillAndExpand" VerticalOptions="StartAndExpand">
            <Button.FontSize>
                <OnPlatform x:TypeArguments="x:Double" iOS="25" Android="20" />
            </Button.FontSize>
        </Button>
    </Grid>

    <Grid x:Name="phraseGrid" Padding="20, 20, 20, 20" BackgroundColor="Transparent" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <Grid.RowDefinitions>
            <RowDefinition Height="6*" />
            <RowDefinition Height="6*" />
            <RowDefinition Height="80*" />
            <RowDefinition Height="13*" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <Grid x:Name="prGrid" Grid.Row="0" Grid.Column="0" 
            Padding="5,0,0,0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
            BackgroundColor>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="50*" />
            </Grid.ColumnDefinitions>
            <Label x:Name="msg1" Style="{StaticResource smallLabel}" Text="msg1" Grid.Row="0" Grid.Column="0" />
            <Label x:Name="msg2" Style="{StaticResource smallLabel}" Text="msg2" Grid.Row="0" Grid.Column="1" />
            <Label x:Name="msg3" Style="{StaticResource smallLabel}" Text="msg3" Grid.Row="0" Grid.Column="2" />
        </Grid>

        <Grid x:Name="siGrid" Grid.Row="1" Grid.Column="0" 
            Padding="5,0,0,0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="25*" />
                <ColumnDefinition Width="50*" />
            </Grid.ColumnDefinitions>
            <Label x:Name="faveLabel" Style="{StaticResource smallLabel}" FontFamily="FontAwesome" Grid.Row="0" Grid.Column="0" />
            <Label x:Name="wordTypeLabel" Style="{StaticResource smallLeftLabel}" Grid.Row="0" Grid.Column="1" />
        </Grid>

        <Grid x:Name="wordGrid" Grid.Row="2" Grid.Column="0" 
            HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <Grid.RowDefinitions>
                <RowDefinition Height="45*" />
                <RowDefinition Height="55*" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
            </Grid.ColumnDefinitions>
            <Grid Grid.Row="0" Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                <Label x:Name="textLabel" FontSize="45" XAlign="Center" VerticalOptions="Center" LineBreakMode="WordWrap" />
            </Grid>
            <Grid x:Name="detailGrid" Grid.Row="1" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Padding="10,0,10,0">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <Label x:Name="detail1" Grid.Row="0" Style="{StaticResource bigLabel}" />
                <Label x:Name="detail2" Grid.Row="1" Style="{StaticResource bigLabel}" />
                <Label x:Name="detail3" Grid.Row="2" Style="{StaticResource bigLabel}" />
            </Grid>
        </Grid>

        <Grid x:Name="buttonGrid" Grid.Row="3" Grid.Column="0" 
            HorizontalOptions="FillAndExpand" VerticalOptions="Center" Padding="20, 0">
            <Button x:Name="aButton" Style="{StaticResource pointButton}" Grid.Column="0" Text="0">
            </Button>
            <Button x:Name="bButton" Style="{StaticResource pointButton}" Grid.Column="1" Text="1">
            </Button>
            <Button x:Name="cButton" Style="{StaticResource pointButton}" Grid.Column="2" Text="2">
            </Button>
            <Button x:Name="dButton" Style="{StaticResource pointButton}" Grid.Column="3" Text="5">
            </Button>
        </Grid>

        <Grid x:Name="tapGrid" Grid.Row="3" Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalOptions="Center">
            <Label x:Name="tapScreenLabel" Style="{StaticResource smallLabel}" />
        </Grid>

    </Grid>
</StackLayout>

【问题讨论】:

  • 不要使用相对布局,因为 Jason Smith 建议使用绝对布局,它有更好的性能。
  • 你有什么链接可以解释更多。我不确定性能是否会成为问题,因为它只是一个没有太大变化的简单页面应用程序。想向您了解更多。我想要相对的原因是因为我希望布局随着屏幕尺寸的变化而变化。谢谢
  • 我正要给你亚当的 J wolf 博客布局食谱,但他似乎不再有博客(出于某种原因)。关于相对布局与绝对布局,您可以对两种布局做同样的事情,即使性能不是问题,您也应该检查一下,这里有一些有用的链接:kimsereyblog.blogspot.mx/2016/09/…developer.xamarin.com/guides/xamarin-forms/user-interface/…youtube.com/watch?v=NDOOr29pCng跨度>
  • 你能添加一个UI的屏幕截图

标签: xamarin xamarin.forms


【解决方案1】:

代码

可以在 GitHub 中找到源代码: https://github.com/brminnick/GridToRelativeLayout

public class RelativeLayoutPage : ContentPage
{
    public RelativeLayoutPage()
    {
        var emptyLabel = new Label
        {
            Text = "Empty Label",
            Margin = new Thickness(10, 0, 10, 0),
            FontSize = 18,
            TextColor = Color.Gray,
            HorizontalTextAlignment = TextAlignment.Center
        };

        var resetPointsButton = new Button
        {
            BackgroundColor = Color.FromHex("E19A3F"),
            Text = "Reset points?",
            TextColor = Color.White,
            FontAttributes = FontAttributes.Bold,
        };
        switch (Device.RuntimePlatform)
        {
            case Device.Android:
                resetPointsButton.FontSize = 20;
                break;
            case Device.iOS:
                resetPointsButton.FontSize = 25;
                break;
        }

        var msg1Label = new Label
        {
            Text = "msg1",
            Margin = new Thickness(0, 26, 0, 0)
        };
        var msg2Label = new Label
        {
            Text = "msg2",
            Margin = new Thickness(0, 26, 0, 0)
        };
        var msg3Label = new Label
        {
            Text = "msg3",
            Margin = new Thickness(0, 26, 0, 0)
        };

        var faveLabel = new Label { Text = "Fave Label" };
        var wordTypeLabel = new Label { Text = "Word Type Label" };

        var textLabel = new Label
        {
            Text = "Text Label",
            FontSize = 45,
            HorizontalTextAlignment = TextAlignment.Center,
            VerticalTextAlignment = TextAlignment.Center
        };

        var detail1Label = new Label
        {
            Text = "Detail 1 Label",
            Margin = new Thickness(10, 0)
        };
        var detail2Label = new Label
        {
            Text = "Detail 2 Label",
            Margin = new Thickness(10, 0)
        };
        var detail3Label = new Label
        {
            Text = "Detail 3 Label",
            Margin = new Thickness(10, 0)
        };

        var zeroButton = new Button
        {
            Text = "0",
            Margin = new Thickness(0, 0, 0, 20)
        };
        var oneButton = new Button
        {
            Text = "1",
            Margin = new Thickness(0, 0, 0, 20)
        };
        var twoButton = new Button
        {
            Text = "2",
            Margin = new Thickness(0, 0, 0, 20)
        };
        var fiveButton = new Button
        {
            Text = "5",
            Margin = new Thickness(0, 0, 0, 20)
        };

        var tapScreenLabel = new Label
        {
            Text = "Tap Screen",
            Margin = new Thickness(0, 0, 0, 20),
            VerticalTextAlignment = TextAlignment.Center,
            VerticalOptions = LayoutOptions.Center
        };

        Func<RelativeLayout, double> GetZeroButtonHeight = parent => zeroButton.Measure(parent.Width, parent.Height).Request.Height;
        Func<RelativeLayout, double> GetOneButtonHeight = parent => oneButton.Measure(parent.Width, parent.Height).Request.Height;
        Func<RelativeLayout, double> GetTwoButtonHeight = parent => twoButton.Measure(parent.Width, parent.Height).Request.Height;
        Func<RelativeLayout, double> GetFiveButtonHeight = parent => fiveButton.Measure(parent.Width, parent.Height).Request.Height;

        var relativeLayout = new RelativeLayout();
        relativeLayout.Children.Add(emptyLabel,
                                    Constraint.Constant(0),
                                    Constraint.Constant(0),
                                    Constraint.RelativeToParent(parent => parent.Width));
        relativeLayout.Children.Add(resetPointsButton,
                                    Constraint.Constant(0),
                                    Constraint.Constant(0),
                                    Constraint.RelativeToParent(parent => parent.Width));
        relativeLayout.Children.Add(msg1Label,
                                    Constraint.Constant(25),
                                    Constraint.RelativeToView(resetPointsButton, (parent, view) => view.Y + view.Height),
                                    Constraint.RelativeToParent(parent => parent.Width * 0.25));
        relativeLayout.Children.Add(msg2Label,
                                    Constraint.RelativeToView(msg1Label, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToView(resetPointsButton, (parent, view) => view.Y + view.Height),
                                    Constraint.RelativeToParent(parent => parent.Width * 0.25));
        relativeLayout.Children.Add(msg3Label,
                                    Constraint.RelativeToView(msg2Label, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToView(resetPointsButton, (parent, view) => view.Y + view.Height),
                                    Constraint.RelativeToParent(parent => parent.Width * 0.5));
        relativeLayout.Children.Add(faveLabel,
                                    Constraint.Constant(25),
                                    Constraint.RelativeToView(msg1Label, (parent, view) => view.Y + view.Height + 20),
                                    Constraint.RelativeToParent(parent => parent.Width * 0.25));
        relativeLayout.Children.Add(wordTypeLabel,
                                    Constraint.RelativeToView(faveLabel, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToView(msg1Label, (parent, view) => view.Y + view.Height + 20),
                                    Constraint.RelativeToParent(parent => parent.Width * 0.25));
        relativeLayout.Children.Add(textLabel,
                                    Constraint.Constant(20),
                                    Constraint.RelativeToView(faveLabel, (parent, view) => view.Y + view.Height + 20),
                                    Constraint.RelativeToParent(parent => parent.Width - 40),
                                    Constraint.RelativeToParent(parent => parent.Height * 0.25));
        relativeLayout.Children.Add(detail1Label,
                                   Constraint.Constant(20),
                                   Constraint.RelativeToView(textLabel, (parent, view) => view.Y + view.Height + 20));
        relativeLayout.Children.Add(detail2Label,
                                   Constraint.Constant(20),
                                   Constraint.RelativeToView(detail1Label, (parent, view) => view.Y + view.Height));
        relativeLayout.Children.Add(detail3Label,
                                   Constraint.Constant(20),
                                   Constraint.RelativeToView(detail2Label, (parent, view) => view.Y + view.Height));
        relativeLayout.Children.Add(zeroButton,
                                    Constraint.Constant(40),
                                    Constraint.RelativeToParent(parent => parent.Height - GetZeroButtonHeight(parent) - 40),
                                    Constraint.RelativeToParent(parent => (parent.Width - 80) / 4));
        relativeLayout.Children.Add(oneButton,
                                    Constraint.RelativeToView(zeroButton, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToParent(parent => parent.Height - GetZeroButtonHeight(parent) - 40),
                                    Constraint.RelativeToParent(parent => (parent.Width - 80) / 4));
        relativeLayout.Children.Add(twoButton,
                                    Constraint.RelativeToView(oneButton, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToParent(parent => parent.Height - GetZeroButtonHeight(parent) - 40),
                                    Constraint.RelativeToParent(parent => (parent.Width - 80) / 4));
        relativeLayout.Children.Add(fiveButton,
                                    Constraint.RelativeToView(twoButton, (parent, view) => view.X + view.Width),
                                    Constraint.RelativeToParent(parent => parent.Height - GetZeroButtonHeight(parent) - 40),
                                    Constraint.RelativeToParent(parent => (parent.Width - 80) / 4));
        relativeLayout.Children.Add(tapScreenLabel,
                                    Constraint.Constant(20),
                                    Constraint.RelativeToView(zeroButton, (parent, view) => view.Y),
                                    Constraint.RelativeToParent(parent => parent.Width - 40));

        Padding = GetPadding();
        Content = relativeLayout;
    }

    Thickness GetPadding()
    {
        switch (Device.RuntimePlatform)
        {
            case Device.iOS:
                return new Thickness(0, 20, 0, 0);
            default:
                return default(Thickness);
        }
    }
}

iOS 演示

Android 演示

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-12
    • 1970-01-01
    • 1970-01-01
    • 2013-08-28
    • 2020-03-06
    • 2019-12-31
    • 2013-09-27
    • 2018-06-24
    相关资源
    最近更新 更多