RelativeLayout ignores RelativeToView - xamarin.forms

Are there any rules for which views you can refer to when using RelativeToView on a RelativeLayout?
It ignores it when I use it like this...
RelativeLayout.YConstraint= "{ConstraintExpression ElementName=main Type=RelativeToView, Property=Height, Factor=0.5}"
It seems to default to RelativeToParent.

Are there any rules for which views you can refer to when using
RelativeToView on a RelativeLayout?
which views you can refer to depending on ElementName you set.
In your code:
RelativeLayout.YConstraint= "{ConstraintExpression ElementName=main Type=RelativeToView, Property=Height, Factor=0.5}"
The Y of this view is half of the height of main, that is 0.5 * main.height.
Here I give you an example:
<RelativeLayout>
<BoxView Color="Red" x:Name="redBox"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
Property=Height,Factor=0.15,Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Width,Factor=1,Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Height,Factor=.8,Constant=0}" />
<BoxView Color="Blue" x:Name="blueBox"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=redBox,Property=Height, Factor=.5, Constant=0}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=redBox,Property=X,Factor=1,Constant=20}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Width,Factor=.5,Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToParent,Property=Height,Factor=.5,Constant=0}" />
<BoxView Color="Orange"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=blueBox,Property=Y,Factor=1,Constant=20}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=blueBox,Property=X,Factor=1,Constant=20}"
RelativeLayout.WidthConstraint="{ConstraintExpression ElementName=blueBox,
Type=RelativeToView,Property=Width,Factor=.5,Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression ElementName=blueBox,
Type=RelativeToView,Property=Height,Factor=.5,Constant=0}" />
</RelativeLayout>
You can see that the height of redBox is 0.8 * height(ContentView). Then I set the blueBox:
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=redBox,Property=Height, Factor=.5, Constant=0}"
So, the Y of blueBox is 0.5* 0.8 * height(ContentView).
Note: Both redBox's superView and blueBox's superView is ContentView.
You should calculate the right height of the View you want.
Refer: relative-layout#usage

Related

How does one position elements in RelativeLayout in Xamarin?

I relation to my question No property, BindableProperty, or event found for “HeightRequest”, or mismatching type between value and property error in Xamarin.Forms, is there any way I can place the username and password entry elements right below the Welcome Label?
So, basically, the app should look like:
[Welcome Label]
[username]
[password]
[login]
I tried using
<RelativeLayout>
<Label
Text="Welcome"
BackgroundColor="Yellow"
TextColor="Green"
FontSize="Medium"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Factor=1, Property=Width, Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Factor=0.1, Property=Height, Constant=0}"
/>
<Entry
Text="Username"
IsPassword="False"
/>
</RelativeLayout>
(Currently just the username field) but to no avail. Why is the entry field being placed over the label?
You could use RelativeToView property to indicate a constraint that is relative to a view
<RelativeLayout>
<Label
x:Name="label"
Text="Welcome"
BackgroundColor="Yellow"
TextColor="Green"
FontSize="Medium"
WidthRequest="100"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Center"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Factor=1, Property=Width, Constant=1}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Factor=0.1, Property=Height, Constant=0}"
/>
<Entry
x:Name="name"
Text="Username"
IsPassword="False"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=label,Property=Width,Factor=0.50,Constant=-50}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=label,Property=Y ,Constant=200}"
/>
<Entry
x:Name="password"
Text="Password"
IsPassword="False"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=name,Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=name,Property=Y ,Constant=50}"
/>
<Button Text="Login" RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToView, ElementName=password,Property=X}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=password,Property=Y ,Constant=200}"/>
</RelativeLayout>
effect like:
Try making something like this & change the alignment according to you.
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label Text="Welcome" HorizontalOptions="Start" Margin="10, 30, 0, 0"/>
<Entry Placeholder="User Id" Margin="10, 20, 0, 0"/>
<Entry Placeholder="Password" IsPassword="True" Margin="10"/>
<Button Text="Login" HorizontalOptions="Center"/>
</StackLayout>
I used stack layout just for basic purpose, its not perfect UI but just for reference.

How can I position an Element using RelativeLayout with respect to an element not at the top?

I'm trying to use a relative layout to position multiple elements. The topmost element is positioned relative to parent, and the element immediately below that has its' YConstraint set by the height of the first element:
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView,
ElementName=TopElement,Property=Height, Factor=1, Constant=0}">
But let's say I want to add a third element, immediately below the second one. How would I set that YConstraint with a ConstraintExpression? Is there a way, in XAML, to set it based on the sum of the heights of the first two elements? If not, how can I achieve this? (I can't use a StackPanel)
Unfortunately we cannot set such constraints in XAML. We can, however achieve it programmatically:
XAML:
<RelativeLayout x:Name="RelativeLayout" BackgroundColor="White">
<BoxView x:Name="BoxView1" BackgroundColor="Red"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Y, Factor=0, Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.1, Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1, Constant=0}"/>
<BoxView x:Name="BoxView2" BackgroundColor="Green"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=BoxView1, Property=Height, Factor=1, Constant=0}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.1, Constant=0}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1, Constant=0}"/>
<BoxView x:Name="BoxView3" BackgroundColor="Blue"/>
</RelativeLayout>
Code-behind:
protected override void OnAppearing()
{
base.OnAppearing();
RelativeLayout.Children.Add(BoxView3, Constraint.RelativeToParent(parent =>
{
return parent.X;
}), Constraint.RelativeToView(BoxView2, (parent, sibling) =>
{
return sibling.Y + sibling.Height;
}), Constraint.RelativeToParent((parent) =>
{
return parent.Width;
}), Constraint.RelativeToParent((parent) =>
{
return parent.Height * .1;
}));
}

RelativeLayout in Xamarin: Can't make a square

I've grabbed the sample project from here: https://developer.xamarin.com/samples/xamarin-forms/BoxView/ListViewColors/
I'm trying to make visual changes, in particular I'm trying to get the color squares to be rounded circles. The color squares are BoxViews in the original, and they use WidthRequest and HeighRequest, both set to 50. This succeeds in making them square. But:
BoxViews don't have a CornerRadius property, so I've made them Frames instead.
I don't want to use points, I want to use RelativeLayout values, so I've tried to set both width and height using Factor=0.1 of the ItemTemplate's Frame.
It doesn't work! No matter what I do, the colored frames are just a weird oblong shape--they're not even square anymore.
What am I doing wrong?
<ListView SeparatorVisibility="None"
BackgroundColor="Transparent"
ItemsSource="{x:Static local:NamedColor.All}"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToParent,
Property=Width,
Factor=1}">
<ListView.RowHeight>
<OnPlatform x:TypeArguments="x:Int32">
<On Platform="iOS, Android" Value="80" />
<On Platform="UWP" Value="90" />
</OnPlatform>
</ListView.RowHeight>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Padding="5">
<Frame x:Name="itemFrame"
BackgroundColor="#bbffffff"
Padding="8"
CornerRadius="10"
HasShadow="false">
<StackLayout Orientation="Horizontal">
<Frame x:Name="colorFrame"
CornerRadius="20"
OutlineColor="Transparent"
BackgroundColor="{Binding Color}"
HasShadow="false"
RelativeLayout.WidthConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=itemFrame,
Property=Width,
Factor=0.1}"
RelativeLayout.HeightConstraint="{ConstraintExpression
Type=RelativeToView,
ElementName=itemFrame,
Property=Width,
Factor=0.1}"/>
<StackLayout>
<Label Text="{Binding FriendlyName}"
FontSize="22"
VerticalOptions="StartAndExpand" />
<Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}"
FontSize="16"
VerticalOptions="CenterAndExpand" />
</StackLayout>
</StackLayout>
</Frame>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativeLayout>
</ContentPage>
The padding in the outer frame seems to have interfered with the shape of your circle, rendering it into an elliptical figure. Removing the padding works and you can obtain a circular shape from your frame.
The corner radius property for a frame usually doesn't render for UWP application. So, you'll need to make a custom renderer for your frame to obtain the circle. As for your listview you can use the following code:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ContentView Padding="5">
<RelativeLayout VerticalOptions="FillAndExpand">
<Frame OutlineColor="Accent" CornerRadius="6" HorizontalOptions="FillAndExpand" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width,Factor=1,Constant=0}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=1,Constant=0}" >
<StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width,Factor=1,Constant=0}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=1,Constant=0}" >
<Frame BackgroundColor="{Binding Color}" CornerRadius="60" RelativeLayout.HeightConstraint ="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.6, Constant=0}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=0.6,Constant=0}"/>
<StackLayout HorizontalOptions="FillAndExpand">
<Label Text="{Binding FriendlyName}" FontSize="22" VerticalOptions="StartAndExpand" />
<Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}" FontSize="16" VerticalOptions = "CenterAndExpand" />
</StackLayout>
</StackLayout>
</Frame>
</RelativeLayout>
</ContentView>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
For frame, custom renderer for UWP:
public class CustomFrame:FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
if (Control != null)
{
var frame = e.NewElement;
Windows.UI.Color frameBG = Windows.UI.Color.FromArgb(
(byte)(frame.BackgroundColor.A * 255),
(byte)(frame.BackgroundColor.R * 255),
(byte)(frame.BackgroundColor.G * 255),
(byte)(frame.BackgroundColor.B * 255));
Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(frame.CornerRadius);
Control.Background = new SolidColorBrush(frameBG);
frame.BackgroundColor = Xamarin.Forms.Color.Transparent;
}
}
}

how i can place 50% control over the tool bar in xamarin forms?

how i can place 50% of control just like 50 % image view over the menu bar and rest 50% of control over the page just as in screenshot ?
I tried to achieve this using relative layout but could not able to do that..
please anyone know help me to design such UI.
<Button HeightRequest="50" WidthRequest="50" BorderRadius="35" BackgroundColor="Aqua"
RelativeLayout.XConstraint= "{ConstraintExpression Type=RelativeToParent, Property=Width, Factor = .5}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor = -.05}" />
You can do this using absolute layout
<AbsoluteLayout BackgroundColor="white">
<BoxView BackgroundColor="Aqua" AbsoluteLayout.LayoutBounds="0
0,1,100" AbsoluteLayout.LayoutFlags="XProportional,YProportional,WidthProportional" />
<Button BackgroundColor="White"
AbsoluteLayout.LayoutBounds=".5,75,70,70" AbsoluteLayout.LayoutFlags="XProportional" BorderRadius="35" />
<Button BackgroundColor="Red" AbsoluteLayout.LayoutBounds=".5
80,60,60" AbsoluteLayout.LayoutFlags="XProportional" BorderRadius="30" />
</AbsoluteLayout>
Reference

Xamarin Forms StackLayout with two Frames not filling up the screen

I see a very strange behavior that I can't understand. I am putting two Frames inside vertically oriented StackLayout. The first Frames' Vertical Option is set to StartAndExpand which renders correctly but the Second Frames' VerticalOption is set to FillAndExpand and for some strange reason it does not follow after the first Frame but from the middle of the screen. I want the Second Frame to immediately follow after the first Frame and take up the whole screen.
Code Below:
<RelativeLayout
x:Name="mainLayout"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}">
<StackLayout
Padding="5,5,5,5"
BackgroundColor="Transparent"
HorizontalOptions="FillAndExpand"
Orientation="Vertical"
Spacing="0"
VerticalOptions="FillAndExpand"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.88}" >
<Frame
OutlineColor="Silver"
BackgroundColor="#FFFFFF"
VerticalOptions="StartAndExpand"
HasShadow="False" >
<StackLayout
BackgroundColor="Transparent">
<RelativeLayout
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
HorizontalOptions="FillAndExpand">
<Label
x:Name="To_Label"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.2}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
FontSize="Micro"
TranslationY="7"
FontAttributes="Bold"
HorizontalOptions="FillAndExpand"
VerticalOptions="CenterAndExpand"
TextColor="#2A84D3"
Text="To:">
</Label>
<Controls:DoneEntry x:Name="To_Entry"
Text="{Binding Model.To}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.22}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.70}"
VerticalOptions="CenterAndExpand"
HorizontalOptions="FillAndExpand" >
<CorcavBehaviors:Interaction.Behaviors>
<CorcavBehaviors:BehaviorCollection>
<PounceBehaviors:EntryTextChanged Command="{Binding ReceipientTextChangeCommand}"/>
</CorcavBehaviors:BehaviorCollection>
</CorcavBehaviors:Interaction.Behaviors>
</Controls:DoneEntry>
</RelativeLayout>
</StackLayout>
</Frame>
<Frame
OutlineColor="Silver"
BackgroundColor="#FFFFFF"
VerticalOptions="FillAndExpand"
HasShadow="False" >
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
BackgroundColor="Transparent">
<Editor
Text="{Binding EmailContent}"
FontSize="Micro"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
>
<CorcavBehaviors:Interaction.Behaviors>
<CorcavBehaviors:BehaviorCollection>
<PounceBehaviors:EditorTextChanged Command="{Binding MessageTextChangedCommand}"/>
</CorcavBehaviors:BehaviorCollection>
</CorcavBehaviors:Interaction.Behaviors>
</Editor>
</StackLayout>
</Frame>
</StackLayout>
<RelativeLayout
Padding="5,5,5,5"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.12}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.88}"
HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand">
<BoxView Color="#3E95D1" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}" HeightRequest="1" />
<Controls:SwipeRightButton x:Name="SendEmail_Button"
BackgroundColor="#2A84D3"
OutlineColor="Silver"
HasShadow="False"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.90}" >
<StackLayout x:Name="ImageLabelContainer"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.90}"
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand">
<Image
x:Name="connect_icon"
Source="sendemailwhite"
Aspect="AspectFill"
BackgroundColor="Transparent"
VerticalOptions="Center"
HorizontalOptions="Center">
</Image>
<Label
VerticalOptions="Center"
HorizontalOptions="Center"
FontSize="Micro"
TextColor="#FFFFFF"
Text="Swipe to Send" />
</StackLayout>
</Controls:SwipeRightButton>
</RelativeLayout>
</RelativeLayout>
Found the problem. The first Frames' VerticalOption should be Start instead of StartAndExpand.

Resources