Xamarin.Forms How to put text/label over a BoxView element? - xaml

I am trying to achieve the result such as in the attached design sample below, I want to add the label SIGN UP and LOGIN over the blue and dark color BoxViews that I successfully created to match the design.
It seems that I cannot add label into a BoxView in Xamarin.Forms so I would like to please know what is a good way to achieve this result.
Currently I am overlapping the BoxViews over the middle column.
<Grid
Margin="0"
ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<!--0 blank -->
<RowDefinition Height="5*" />
<!--1 logo -->
<RowDefinition Height="15*" />
<!--2 blank -->
<RowDefinition Height="5*" />
<!--3 main title-->
<RowDefinition Height="5*" />
<!--4 main title -->
<RowDefinition Height="5*" />
<!--5 main title-->
<RowDefinition Height="5*" />
<!--7 blank-->
<RowDefinition Height="15*" />
<!--8 subtitle-->
<RowDefinition Height="5*" />
<!--9 subtitle-->
<RowDefinition Height="5*" />
<!--10 blank-->
<RowDefinition Height="0*" />
<!--11 signup login bar-->
<RowDefinition Height="7*" />
<!--12 signup login bar-->
<RowDefinition Height="7*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="65*" />
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="30*" />
</Grid.ColumnDefinitions>
<Image Source="homePageLogo.png"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
HorizontalOptions="Center"
HeightRequest="120"
Aspect="AspectFit">
</Image>
<Label
Text="{Binding MainTitle}"
Grid.Row="3"
Grid.RowSpan="4"
Grid.Column="0"
Grid.ColumnSpan="3"
FontFamily="Gibson"
FontAttributes="Bold"
TextColor="White"
FontSize="50"
LineBreakMode="WordWrap"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center">
</Label>
<Label
Text="{Binding SubTitle}"
Grid.Row="8"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="3"
FontFamily="Poppins"
FontAttributes="Bold"
TextColor="White"
FontSize="Large"
LineBreakMode="WordWrap"
HorizontalOptions="CenterAndExpand"
HorizontalTextAlignment="Center">
</Label>
<!-- This is the boxview that should contain the LOGIN label -->
<BoxView
Grid.Row="11"
Grid.Column="1"
Grid.ColumnSpan="2"
Grid.RowSpan="2"
BackgroundColor="#2F3237">
</BoxView>
<!-- This is the boxview that should contain the SIGNUP label -->
<BoxView
Grid.Row="11"
Grid.Column="0"
Grid.ColumnSpan="2"
Grid.RowSpan="2"
BackgroundColor="#337EF3"
CornerRadius="0,15,0,15">
</BoxView>
</Grid>

Related

How to set controls in Xamarin Form to get a similar and relative UI in every phone screen sizes?

I want to make a UI like this:
This UI should correspond to different phone screen sizes.
I started to write this XAML code:
<StackLayout>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Frame BackgroundColor="Transparent"/>
</Grid>
<Grid Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10"/>
</Grid>
<Grid Grid.Row="1" Padding="0,40,0,0">
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10"/>
</Grid>
</Grid>
<Entry Grid.Row="0" Grid.Column="1" MaxLength="30" Placeholder="User Name:" ClearButtonVisibility="WhileEditing"/>
<Entry Grid.Row="1" Grid.Column="1" MaxLength="30" Placeholder="Password:" ClearButtonVisibility="WhileEditing" IsPassword="True"/>
<Image Source="User.png" Scale="0.6"/>
<Image Source="Lock.png" Scale="0.6"/>
<Button Text="Login"/>
</StackLayout>
I know that Those images must be in the Grid node above. But I cannot set those Entry and user/pass logos correctly. Those buttons are images in the resource folder.
Please help me to set a UI similar to this image.
One grid is enough, you can remove one.
You can refer to the following code:
<StackLayout BackgroundColor="#1E90FF" Orientation="Vertical">
<Grid Margin="20" >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10" Grid.Row="0" Grid.ColumnSpan="2" />
<Entry Grid.Row="0" Grid.Column="0" MaxLength="30" Placeholder="User Name:" ClearButtonVisibility="WhileEditing" />
<Image Source="head.png" Scale="0.6" Grid.Row="0" Grid.Column="1"/>
<Frame HeightRequest="30" BackgroundColor="White" CornerRadius="10" Grid.Row="1" Grid.ColumnSpan="2"/>
<Entry Grid.Row="1" Grid.Column="0" MaxLength="30" Placeholder="Password:" ClearButtonVisibility="WhileEditing" IsPassword="True"/>
<Image Source="Lock.png" Scale="0.6" Grid.Row="1" Grid.Column="1"/>
</Grid>
<Button Text="Login"/>
</StackLayout>
The result is:

Xamarin.Forms: how to position a Circle Image above and between 2 ScrollLayout

I work on a Xamarin.Forms app containing a HomePage based on:
an Image at the top background of the screen
a list of items displayed in a ScrollView
The ScrollView can recover the Image if the list contain many informations.
This looks like this:
The XAML looks like this:
<Grid RowSpacing="0"
BackgroundColor="{StaticResource Gray-050}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<!-- Header view -->
<ScrollView>
<ContentView x:Name="headerView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- the BoxView will be replaced by an Image -->
<BoxView x:Name="headerImage"
HeightRequest="280"
BackgroundColor="Yellow" />
</Grid>
</ContentView>
</ScrollView>
<!-- List view -->
<ScrollView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Main container -->
<yummy:PancakeView CornerRadius="16,16,0,0"
Padding="0,10,0,0"
BackgroundColor="{StaticResource Gray-050}"
Grid.Row="1">
<StackLayout BackgroundColor="Transparent"
Spacing="16" Margin="16">
<!-- Phone container -->
<yummy:PancakeView Style="{StaticResource YummyHomeFrame}"
Padding="16">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Style="{StaticResource HomePageHeaderLabelStyle}"
Text="Phone Number" />
<Label Grid.Row="1"
Style="{StaticResource HomePageLabelStyle}"
Text="+33 6 20 10 70 40" />
</Grid>
</yummy:PancakeView>
<!-- Other containers -->
</StackLayout>
</yummy:PancakeView>
</Grid>
</Grid>
</ScrollView>
</Grid>
</Grid>
I would like to display a circle logo between the 2 ScrollViews, just above the MainContainer, something like this:
But I don't have managed to achieve this, and I don't know if it's possilbe...
You could have a try with RelativeLayout to achieve that.
Here is similar sample code:
<ScrollView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Main container -->
<RelativeLayout>
<Frame CornerRadius="16" x:Name="MainFrame"
Padding="0,10,0,0"
BackgroundColor="LightBlue"
Grid.Row="1">
<StackLayout BackgroundColor="Transparent"
Spacing="16"
Margin="16">
<!-- Phone container -->
<Frame Padding="16">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="Phone Number" />
<Label Grid.Row="1"
Text="+33 6 20 10 70 40" />
</Grid>
</Frame>
<!-- Other containers -->
</StackLayout>
</Frame>
<BoxView CornerRadius="25"
BackgroundColor="AliceBlue"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Property=Width,Factor=0.45}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Property=Y,Constant=-20}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Constant=100}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToView, ElementName=MainFrame, Constant=100}" />
</RelativeLayout>
</Grid>
</Grid>
</ScrollView>
The effect:
Add you circle logo at the same level of the container.
<!-- Items view -->
<ScrollView HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Grid
ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Container -->
<Frame ...>
<!-- Yoour logo -->
<Frame
Grid.Row="1"
Margin="0,-40,0,0"
BackgroundColor="Green"
CornerRadius="40"
HeightRequest="40"
HorizontalOptions="Center"
VerticalOptions="Start"
WidthRequest="40" />
</Grid>
</Grid>
</ScrollView>
Check the demo:
As I didn't use the nugget package, I just replaced the pancake view with a frame. And you can adjust the logo size, margin as you wish.
Btw, your structure is a bit complex or redundant, could be a 4-level main structure as below:
<Grid x:Name="mainGrid">
<!-- Header view -->
<BoxView (or Image).../>
<!-- Items view -->
<ScrollView ...>
<Grid ...>
<!-- Container -->
<Frame ...>
<!-- logo -->
<Frame (or Image)...>
</Grid>
</ScrollView>
</Grid>
Thank you #Shaw and #Junior Jiang - MSFT
There are so 2 solutions: with or without RelativeLayout.
The version without RelativeLayout was given by #Shaw.
<Grid RowSpacing="0"
BackgroundColor="LightGray"
x:Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<!-- Header view -->
<ScrollView>
<ContentView x:Name="headerView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- the BoxView can be replaced by an Image -->
<BoxView x:Name="headerImage"
HeightRequest="280"
BackgroundColor="Yellow" />
</Grid>
</ContentView>
</ScrollView>
<!-- Content View -->
<ScrollView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!-- Frame Container-->
<Frame x:Name="MainFrame"
CornerRadius="16"
Padding="0,10,0,0"
BackgroundColor="LightGray"
Grid.Row="1">
<StackLayout BackgroundColor="Transparent"
Spacing="16" Margin="16,48,16,16">
<!-- Phone Frame -->
<Frame Padding="16">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="Phone Number" />
<Label Grid.Row="1"
Text="+33 6 20 10 70 40" />
</Grid>
</Frame>
<!-- Other Frames -->
<!-- ... -->
</StackLayout>
</Frame>
<!-- No RelativeLayout positioned item -->
<BoxView Grid.Row="1"
CornerRadius="45"
BackgroundColor="DarkBlue"
WidthRequest="90" HeightRequest="90"
VerticalOptions="Start" HorizontalOptions="Center"
Margin="0,-45,0,0" />
</Grid>
</Grid>
</ScrollView>
</Grid>
</Grid>
The version with RelativeLayout is based on #Junior Jiang - MSFT suggestion:
<Grid RowSpacing="0"
BackgroundColor="LightGray"
x:Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<!-- Header View -->
<ScrollView>
<ContentView x:Name="headerView"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- the BoxView can be replaced by an Image -->
<BoxView x:Name="headerImage"
HeightRequest="280"
BackgroundColor="Yellow" />
</Grid>
</ContentView>
</ScrollView>
<!-- Content View -->
<ScrollView HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<Grid ColumnSpacing="0"
RowSpacing="0"
VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="140" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout Grid.Row="1">
<RelativeLayout>
<!-- Frame container -->
<Frame x:Name="MainFrame"
CornerRadius="16"
Padding="0,10,0,0"
BackgroundColor="LightGray"
Grid.Row="1">
<StackLayout BackgroundColor="Transparent"
Spacing="16" Margin="16,48,16,16">
<!-- Phone Frame -->
<Frame Padding="16">
<Grid RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label Text="Phone Number" />
<Label Grid.Row="1"
Text="+33 6 20 10 70 40" />
</Grid>
</Frame>
<!-- Other Frames -->
<!-- ... -->
</StackLayout>
</Frame>
<!-- RelativeLayout positioned item -->
<BoxView CornerRadius="45"
BackgroundColor="DarkBlue"
WidthRequest="90" HeightRequest="90"
VerticalOptions="Center" HorizontalOptions="Center"
RelativeLayout.XConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=0.5,
Constant=-45}"
RelativeLayout.YConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=MainFrame,
Property=Y,Constant=-45}" />
</RelativeLayout>
</StackLayout>
</Grid>
</ScrollView>
</Grid>
</Grid>

How can I not stretch out my image button in XAML

I have these search bars and image buttons using Xamarin Forms, but the image button is getting stretched out, and I don't know how I can fix it with the XAML set up that I have.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0" Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center"/>
<ImageButton Grid.Row="0" Grid.Column="1"
Margin="4,5,4,4"
Command="{Binding Filter}" Source="filter.png" BackgroundColor="Transparent"></ImageButton>
</Grid>
The problem is, that if I set the image button to a specific width, to make it universal among devices, I don't know how to tell XAML to just stretch the search bar up to the image. What can I do?
I have tried with shared code , however it works in my local site . I think difference should be the PNG image . To clearly show the size of the ImageButton, I added a background color to illustrate it.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect as follow :
Here is the PNG image info :
However , I can reproduce your problem with my PNG image . If I set Aspect="Fill" and Width of Column is * as follow :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Aspect="Fill"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effects :
About Solution , I have found three here :
First , if you can get a standard PNG file as minie , there will no problem .
Second , you can add Aspect="AspectFit" into ImageButton as Jason's suggestion .But that's not enough for your PNG image .You also need to set Width for its Column as follow :
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
Aspect="AspectFit"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect :
Third , based on my reproduced code , adding HorizontalOptions="Center" for ImageButton also can solve it .
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<SearchBar Grid.Row="0"
Grid.Column="0"
Placeholder="Search"
Text="{Binding SearchText}"
FontSize="Medium"
VerticalOptions="Center"
Margin="0,4,0,0"
VerticalTextAlignment="Center" />
<ImageButton Grid.Row="0"
Grid.Column="1"
HorizontalOptions="Center"
Aspect="Fill"
Margin="4,5,4,4"
Source="search.png"
BackgroundColor="Red"></ImageButton>
</Grid>
The effect :
Although the image of three solutions shows the same , however the Bounds of their backgroud Frame is different .
use the Aspect property
<ImageButton Aspect="AspectFit" ...

Different TapGestureRecognizer for each row

<ContentView>
<Grid InputTransparent="True">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Spacing="0"
Grid.Row="0"
VerticalOptions="Center">
<Label Text="Algebra"/>
<Label Text="number 1" />
</StackLayout>
<Switch IsToggled="True"
VerticalOptions="Center"
Grid.Row="1"
Grid.Column="1"
/>
<StackLayout Spacing="0"
Grid.Row="1"
VerticalOptions="Center">
<Label Text="Arithmetics" />
<Label Text="number 2" />
</StackLayout>
<Switch IsToggled="True"
VerticalOptions="Center"
Grid.Column="1"
/>
</Grid>
</ContentView>
I have two rows with each having 2 labels and a switch. How can I invoke two different Tap events, for each row. Something like this:
<ROW1?.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped1" />
</ROW?.GestureRecognizers>
<ROW2?.GestureRecognizers>
<TapGestureRecognizer Tapped="OnTapped2" />
</ROW?.GestureRecognizers>
I'm new, but it seems Switch toggle doesn't work while in grid, which is strange.
UI image:
Since you can't simply apply a gesture to an entire grid row,
I decided to just use Switch built-in functionality for my UI.
And all I did was add two different methods for each Switch:
<Grid InputTransparent="True">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackLayout Spacing="0"
Grid.Row="0"
VerticalOptions="Center">
<Label Text="Algebra"/>
<Label Text="number 1" />
</StackLayout>
<Switch IsToggled="True"
Toggled="method2"
VerticalOptions="Center"
Grid.Row="1"
Grid.Column="1"
/>
<StackLayout Spacing="0"
Grid.Row="1"
VerticalOptions="Center">
<Label Text="Arithmetics" />
<Label Text="number 2" />
</StackLayout>
<Switch IsToggled="True"
Toggled="method2"
VerticalOptions="Center"
Grid.Column="1"
/>
</Grid>

Both Label in Grid (same column, diff row) move when text changed. Why?

Video showing the simulator: https://youtu.be/3ajany0iaCw
The codes:
<Grid HorizontalOptions="Center" VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Switch Grid.Column="0"
HorizontalOptions="Center"
IsToggled="{Binding SwitchToggled}"/>
<Label Grid.Column="1"
HorizontalOptions="Center"
Text="{Binding SwitchToggled,
Converter={StaticResource Key=boolToStrConv}}"/>
<Switch Grid.Column="0" Grid.Row="1"
HorizontalOptions="Center"
x:Name="switch2"/>
<Label Grid.Column="1" Grid.Row="1"
HorizontalOptions="Center"
Text="{Binding Source={x:Reference switch2},
Path=IsToggled,
Converter={StaticResource Key=boolToStrConv}}"/>
</Grid>
My expectation is that no matter how the Label's text length is changed, it would both be centered - considering that both of them has a HorizontalOptions Center.
Why did this happened and how do I fix this?
You need to look at the container that is grid is within and the fact that you are centering (floating) your grid within that container.
Assign a background color to your grid and a different one to its container and you will see that its size depends upon what it is contains since you are * (star) its size and the grid itself is "floating" in the center of its container, change the contents of the grid, the size of the grid changes:
<Grid VerticalOptions="Center" HorizontalOptions="Center" BackgroundColor="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Switch Grid.Column="0" HorizontalOptions="Center" BackgroundColor="Red" x:Name="switch1" />
<Label Grid.Column="1" HorizontalOptions="Center" BackgroundColor="Red" Text="False" x:Name="label1" />
<Switch Grid.Column="0" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" x:Name="switch2" />
<Label Grid.Column="1" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" Text="False" x:Name="label2" />
</Grid>
Lock the grid to fill its parent's width (via StartAndExpand in my example) and changing your label's text content will not cause your toggle's start position to move...
<Grid VerticalOptions="StartAndExpand" HorizontalOptions="FillAndExpand" BackgroundColor="Gray">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Switch Grid.Column="0" HorizontalOptions="Center" BackgroundColor="Red" x:Name="switch1" />
<Label Grid.Column="1" HorizontalOptions="Center" BackgroundColor="Red" Text="False" x:Name="label1" />
<Switch Grid.Column="0" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" x:Name="switch2" />
<Label Grid.Column="1" Grid.Row="1" HorizontalOptions="Center" BackgroundColor="Green" Text="False" x:Name="label2" />
</Grid>