Wednesday, August 30, 2017

How can I change a <StackLayout> <Grid> screen to use <RelativeLayout>?

Leave a Comment

I have this code that's currently a combination of and

I would like to move to a relative layout and have not seen so many examples of that. Would appreciate any suggestions on how this could be accomplished.

Some points about the XAML.

  • Either emptyGrid or phraseGrid appear on the screen
  • Either buttonGrid or tapGrid appear on the screen
  • The vertical center of the buttons and the tap label should be the same position. So that when the buttons are not showing a tap label appears at the same vertical buttons as the buttons.
  • The Frame appears inside a tabbed page

I realize this is a bit more than a simple question but I'm sure it would be of interest to others. As the answer might be quite involved I'll open up a 250 point bounty for this in a couple of days.

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

1 Answers

Answers 1

Code

The source code for this can be found in 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 Demo

enter image description here

Android Demo

enter image description here

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment