xamarin - 如何更改 <StackLayout> <Grid> 屏幕以使用 <RelativeLayout>?

标签 xamarin xamarin.forms

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

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

关于 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>
    

    最佳答案

    代码

    其源代码可以在 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 演示

    enter image description here

    安卓演示

    enter image description here

    关于xamarin - 如何更改 <StackLayout> <Grid> 屏幕以使用 <RelativeLayout>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45640548/

    相关文章:

    sqlite - Xamarin UWP 和 Azure 移动服务离线 SQLite 同步 - 使用 .Net Native Toolchain 在 Release模式下构建时出现问题

    xamarin.forms - 如何在自定义呈现器中呈现 xamarin.forms View

    xamarin - 为什么 Xamarin 中的 Context.User.Identity.Name 为空?

    带有自动千位和小数分隔符的 Xamarin.Forms 条目

    c# - 将 JObject 转换为动态对象

    c# - OSX Xamarin,未找到 System.Drawing 命名空间

    c# - MvvmCross Android转换器导致光标跳转

    c# - 如何使用 OxyPlot 在 Xamarin.Forms 可移植应用程序中创建图表?

    c# - Xamarin 表格 : iOS Linking Framework

    xcode - 在钥匙串(keychain)中找不到有效的 iOS 代码签名 key 。您需要申请一个代码签名证书