Xamarin margins are different between two resolutions (devices) - xaml

I have a page in xamarin with a couple of frames, all with an image (color) and text. However, i'm facing the problem that the margins of the images (colors) look different on different phones (resolutions). As you can see on the image below, the images are in the right position on the Galaxy S8 (resolution 1440x2960) and at the wrong position on the Galaxy S10e (resolution 1080 x 2280).
I am using the following code for the frames:
<Grid ColumnSpacing="12.5" RowSpacing="12.5" Padding="10" HeightRequest="500">
<Grid.RowDefinitions>
<RowDefinition Height="0.8*" />
<RowDefinition Height="4.5*" />
<RowDefinition Height="1.5*" />
<RowDefinition Height="1.5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Frame x:Name="frame_Sport" Grid.Row="2" Grid.Column="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="Sport_Clicked"/>
</Frame.GestureRecognizers>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" >
<Label Text=" Sport" FontSize="18"/>
</StackLayout>
<StackLayout Orientation="Vertical" >
<Label x:Name="txt_Sport" FontSize="18"/>
</StackLayout>
<Image Source="mark_green.png" Scale="0.17" Margin="-110,-137,0,0"/>
</StackLayout>
</Frame>
<Frame x:Name="frame_Voeding" Grid.Row="2" Grid.RowSpan="2" Grid.Column="1" >
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="Voeding_Clicked"/>
</Frame.GestureRecognizers>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<Label Text=" Voeding" FontSize="18" />
<Label x:Name="txt_Voeding1" FontSize="18" Margin="0,-0.6"/>
<Label x:Name="txt_Voeding2" FontSize="18" Margin="0,-0.6"/>
<Label x:Name="txt_Voeding3" FontSize="18" Margin="0,-0.6"/>
<Label x:Name="txt_Voeding4" FontSize="18" Margin="0,-0.6"/>
<Label x:Name="txt_Voeding5" FontSize="18" Margin="0,-0.6"/>
<Label x:Name="txt_Voeding6" FontSize="18" Margin="0,-0.6"/>
<Image Source="mark_red.png" Scale="0.17" Margin="-110,-280,0,0"/>
</StackLayout>
</Frame>
<Frame x:Name="frame_Slaap" Grid.Row="3" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<Frame.GestureRecognizers>
<TapGestureRecognizer Tapped="Slaap_Clicked"/>
</Frame.GestureRecognizers>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" >
<Label Text=" Slaap" FontSize="18" />
</StackLayout>
<StackLayout Orientation="Vertical">
<Label x:Name="txt_Slaap" FontSize="18" />
</StackLayout>
<Image Source="mark_blue.png" Scale="0.17" Margin="-110,-137,0,0"/>
</StackLayout>
</Frame>
</Grid>
Why are the images (colors) looking different on both phones, how do I fix this?

The values for Margin are in absolute units (pixels).
The Frame which contains the StackLayout has a different absolute width on every device. Therefore your positioning of the icon will differ if the resolution or dpi differs.
In your case I would create a Horizontal Stacklayout with the Image and the label like that:
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
<StackLayout Orientation="Horizontal">
<Image Source="mark_red.png" Scale="0.17"/>
<Label Text="Voeding" FontSize="18" />
</StackLayout>
<Label x:Name="txt_Voeding1" FontSize="18" Margin="0,-0.6"/>
...
</StackLayout>

I have a page in xamarin with a couple of frames, all with an image (color) and text. However, I'm facing the problem that the margins of the images (colors) look different on different phones (resolutions). As you can see on the image below, the images are in the right position on the Galaxy S8 (resolution 1440x2960) and at the wrong position on the Galaxy S10e (resolution 1080 x 2280).
The reason this is happening is that different devices have a different density. When it comes to Margin it is a double value and Xamarin Forms converts this double values into platform specific types (for eg Dp's, Points) respectively. Hence every device responds to the same margin in a different way based on its own size and density.
In the same way, density also affects the colour. The human perception for colour changes if the device has a denser pixels even though it is the same color but it looks a little different to us! Basically, The denser the pixels are in your device the more vivid the colour is to the naked eye.
Now coming back to the issue the reason your Margin is looking different is the same reason I explained above, Now to overcome this issue you might want to either remove the StackLayout use Grid instead and define a proper Column definition in a way that they align properly.
<Grid>
<Grid.ColumnDefinitions> <--<Define these as they suit you>-->
.
.
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="mark_red.png" Scale="0.17"/>
<Label Grid.Column="1" Text="Voeding" FontSize="18" />
</Grid>
Or Increase the Spacing property of the StackLayout so it adds a little extra space between the Image and the Label:
<StackLayout Orientation="Horizontal" Spacing="10"> <--<Default spacing is 6>-->
<Image Source="mark_red.png" Scale="0.17"/>
<Label Text="Voeding" FontSize="18" />
</StackLayout>
Update:
Your XAML should look like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Source="mark_red.png" Scale="0.17"/>
<Label Grid.Column="1" Text="Voeding" FontSize="18" />
<StackLayout Grid.Row="1" Grid.ColumnSpan="2" >
<Label x:Name="txt_Voeding1" FontSize="18" Margin="0,-3"/>
<Label x:Name="txt_Voeding2" FontSize="18" Margin="0,-3"/>
<Label x:Name="txt_Voeding3" FontSize="18" Margin="0,-3"/>
<Label x:Name="txt_Voeding4" FontSize="18" Margin="0,-3"/>
<Label x:Name="txt_Voeding5" FontSize="18" Margin="0,-3"/>
<Label x:Name="txt_Voeding6" FontSize="18" Margin="0,-3"/>
</StackLayout>
</Grid>

Related

Xamarin iOS - How to get StackLayout to auto size to nested contents?

I have the following XAML :
<StackLayout>
<Grid IsVisible="{Binding isVisible}" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<behaviors:Expander x:Name="MainExpander" CollapseAnimationLength="500" IsExpanded="false" >
<behaviors:Expander.Header>
<Grid HorizontalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Frame HeightRequest="40" WidthRequest="40" CornerRadius="20" HorizontalOptions="Start" VerticalOptions="Center" Margin="20" Padding="0" BackgroundColor="Maroon">
<Label Text="{Binding student_initial}" TextColor="White" HorizontalOptions="Center" VerticalOptions="Center" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
</Frame>
<StackLayout Grid.Column="2" HorizontalOptions="StartAndExpand" VerticalOptions="Center" Margin="20">
<Label x:Name="StudentName" Text="{Binding student_fullname}"></Label>
<Label x:Name="StudentID" IsVisible="false" Text="{Binding student_unique_id}"></Label>
</StackLayout>
</Grid>
</behaviors:Expander.Header>
<Grid RowSpacing="0" HorizontalOptions="FillAndExpand" HeightRequest="240" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Text="Messages" Clicked="Button_Clicked"></Button>
<Button x:Name="btnTopUp" Grid.Row="1" Text="Quick Topup" Clicked="Button_Clicked" IsVisible="{Binding topup_product_id, Converter={StaticResource IsNotNullOrEmptyConverter}}"></Button>
<Button Grid.Row="2" Text="Payments" Clicked="Button_Clicked"></Button>
</Grid>
<!--TODO: Look at adding a balance for childrens topups?-->
</behaviors:Expander>
</Grid>
</StackLayout>
I am trying to hide and show the grid as follows :
<Grid IsVisible="{Binding isVisible}" ...
The issue is that nothing shows as it looks like the StackLayout is unable to work out how high it needs to be. I can't explicitly set the height property as it depends if the expander is expanded or not. Is there a way to make the stack layout height auto size ? Thank you.
Replace StackLayout with Grid , set its HorizontalOptions and VerticalOptions as Start .
<Grid BackgroundColor="Red" HorizontalOptions="Start" VerticalOptions="Start">
<Grid IsVisible="false" ...
See the following screen shot in all of the scenarios (red color represents the root Grid)
Gird invisible
Grid visible (none-expanded)
Grid visible (expanded)

Xamarin stacking text below an image

I am trying to figure out how to center the image and text and push the text "Cache 3" directly below the image without the bottom red space. This stacklayout is in a collection so the images are of different heights hence I can't set a HeightRequest per se.
This is my XAML:
<StackLayout>
<Frame
Margin="10"
Padding="0"
BorderColor="{StaticResource Gray-500}"
CornerRadius="5"
HasShadow="False"
HorizontalOptions="Center"
VerticalOptions="FillAndExpand">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image
Grid.Row="0"
Margin="15"
Aspect="AspectFit"
BackgroundColor="Red"
Source="{Binding Image, Converter={StaticResource BytesToImageSource}}" />
<Label
Grid.Row="1"
Padding="15,0,15,15"
FontSize="18"
HorizontalTextAlignment="Center"
Text="{Binding Data}"
TextColor="{StaticResource Gray-900}"
VerticalTextAlignment="Center" />
</Grid>
</Frame>
</StackLayout>

ListView HasUnevenRows does not work in xamarinforms

good afternoon, i have a listview with grid with two labels in the first column and an image in the second column, it happens that the image is disrespecting, without the image the label is in the correct size.
My problem is that the label doesn’t show all her content when it has the image
When you have the image the labels are wrong. image with resized error
Without the image, which would be expected but I don't know how to fix it for the cells to resize
error-free image
I've tried everything, if anyone can help me thank you
mycode
<ListView
x:Name="ListView_ListaRotas"
HasUnevenRows="True"
IsPullToRefreshEnabled="True"
ItemTapped="ListView_ListaRotas_ItemTapped"
Refreshing="ListView_ListaRotas_Refreshing"
SeparatorVisibility="None">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Frame
Margin="0,5"
Padding="5,0"
BorderColor="Gray"
Opacity="{Binding PermiteCheck, Converter={StaticResource Key=OpacityConverter}}">
<Grid
Margin="0"
Padding="1,0"
ColumnSpacing="0"
RowSpacing="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackLayout HorizontalOptions="StartAndExpand" VerticalOptions="CenterAndExpand">
<Label
FontAttributes="Bold"
FontSize="18"
HorizontalTextAlignment="Start"
Text="{Binding Ds_Observacao}"
VerticalTextAlignment="Start" />
<StackLayout Orientation="Horizontal">
<Label
FontSize="Medium"
Text="{Binding Nm_Posto}"
VerticalTextAlignment="Center" />
<Image
Aspect="AspectFit"
HeightRequest="20"
IsVisible="{Binding HasSketch}"
Source="rascunho.png"
WidthRequest="20" />
</StackLayout>
</StackLayout>
<Image
Grid.Column="1"
Aspect="AspectFit"
HorizontalOptions="EndAndExpand"
Source="{Binding TimeLine}"
VerticalOptions="Center" />
</Grid>
</Frame>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Xamarin Grid does not split evenly

I want two labels contained within a ListView DataTemplate Cell to split evenly horizontally across the screen.
From my understanding,
if you use a Grid and set the two ColumnDefinitions to 1* it should work. I tried this and it does not display as expected.
I had to add a large WidthRequest to the first Label to get it to work.
I also tried setting the HorizonalOptions on the Grid and labels to FillAndExpand and that had no results.
<ViewCell>
<Frame HasShadow="true" Margin="2">
<StackLayout Orientation="Horizontal" Margin="0,0,0,0" >
<StackLayout WidthRequest="20" BackgroundColor="{Binding RYGStatusColor}" >
<Label Text="{Binding RYGStatusLetter}" HorizontalTextAlignment="Center"
FontSize="Medium" FontAttributes="Bold" TextColor="White" />
</StackLayout>
<StackLayout Orientation="Vertical">
<Label Text="{Binding ProgramName}" FontSize="Medium" FontAttributes="Bold" />
<Label Text="{Binding DesignCustomerName}" FontSize="Small" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0"
Text="{Binding EstimatedTotalValue, Converter={StaticResource CurrencyDisplay}}"
FontSize="Small" FontAttributes="Bold" WidthRequest="1024" />
<!-- WidthRequest is a hack to force the width to be equal across the screen. -->
<Label Grid.Row="0" Grid.Column="1" FontSize="Small">
<Label.FormattedText>
<FormattedString>
<Span Text="Modified: " />
<Span Text="{Binding ModifiedDate, StringFormat='{0:M/d/yy}', Converter={StaticResource LocalTime}}}" />
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
</StackLayout>
</StackLayout>
</Frame>
</ViewCell>
Without the WidthRequest hack, I get these results: Actual Results
Row 1
"Label1 Label2 "
Row 2
"Label1 Label2 "
With the hack, I get expected results:Expected Results
Row 1
"Label1 Label2 "
Row 2
"Label1 Label2 "
I suspect the Grid is splitting itself correctly, but it is not taking up the full space that you are expecting. Try adding HorizontalOptions="FillAndExpand" to the Grid itself and report back.
I want two labels contained within a ListView DataTemplate Cell to split evenly horizontally across the screen.From my understanding, if you use a Grid and set the two ColumnDefinitions to 1* it should work. I tried this and it does not display as expected.
I use your code in ListView datetemplate, and don't use widthrequest, I get the following result. Xamarin.Form version is 3.4.0.1008975.
Here is the code:
<ContentPage.Content>
<ListView ItemsSource="{Binding models}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
BackgroundColor="Blue"
FontAttributes="Bold"
FontSize="Small"
Text="{Binding str1}" />
<!-- WidthRequest is a hack to force the width to be equal across the screen. -->
<Label
Grid.Row="0"
Grid.Column="1"
BackgroundColor="Yellow"
FontSize="Small">
<Label.FormattedText>
<FormattedString>
<Span Text="Modified: " />
<Span Text="{Binding str2}" />
</FormattedString>
</Label.FormattedText>
</Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>

Xamarin forms - unwanted extra space under TableView

I am creating my first Android app. I want to show TableView with some input fields and then a button to process the inputs.
I don't know why but there is extra space under TableView or the button is aligned to the bottom but it is opposite to the settings.
Can you help me fix it?
<StackLayout Orientation="Vertical" VerticalOptions="Start" Padding="20,15,20,0" Spacing="0">
<Label Text="This is TableView"></Label>
<TableView Intent="Settings" VerticalOptions="Start">
<TableRoot>
<TableSection>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="item 1"/>
<Entry></Entry>
</StackLayout>
</ViewCell>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Label Text="item 2"/>
<Entry></Entry>
</StackLayout>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
<Label Text="TableView - END"></Label>
<Button Text="My button" TextColor="DodgerBlue" VerticalOptions="Start" HorizontalOptions="Fill" Margin="40, 10, 40, 10"/>
<Frame VerticalOptions="StartAndExpand" BackgroundColor="Transparent" BorderColor="Black">
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Horizontal" HorizontalOptions="Fill">
<Label Text="aaaa" HorizontalOptions="StartAndExpand"></Label>
<Label Text="value" HorizontalOptions="End"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="aaaa"></Label>
<Label Text="value"></Label>
</StackLayout>
<StackLayout Orientation="Horizontal">
<Label Text="aaaa"></Label>
<Label Text="value"></Label>
</StackLayout>
</StackLayout>
</Frame>
</StackLayout>
Your best option is to define the RowHeight for each cell, and then specify the HeightRequest for the tableview. this way you can define the space it will occupy
<TableView Margin="0" Intent="Settings" HeightRequest="120" RowHeight="60" VerticalOptions="Start">
Unfortunately, this is how Xamarin.Forms TableView/ListView works. It is not expected to have anything below it. If you need something below you can either set the height of TableView manually or to put the content in the last cell, neither thing is perfect but in any case you need to look for some workaround as this is behavior by design (it would be a bit easier if you could use the ListView instead of TableView).
As you were asking what you can do besides using a TableView, of course a Grid would be possible, please see the following example:
<Grid VerticalOptions="StartAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" /> <!-- for the label -->
<ColumnDefinition Width="*" />
<Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1" /> <!-- For the separator, you might have to experiment with the height -->
<RowDefinition Height="*" />
<RowDefinition Height="1" />
</Grid.RowDefinitions>
<Label Text="Item 1" />
<Entry Grid.Row="0" Grid.Column="1" />
<BoxView BackgroundColor="Black"
HeightRequest="1"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2" /> <!-- The separator -->
<Label Grid.Row="2" Grid.Column="0" Text="Item 2" />
<Entry Grid.Row="2" Grid.Column="1" />
<BoxView BackgroundColor="Black"
HeightRequest="1"
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="2" /> <!-- The separator -->
</Grid>
I am using BoxViews with a black background color and a HeightRequest of 1 for the separator. You might have to experiment with the color and the height to get the results you want. Values below 1 are possible and result in finer lines. In a real world example I've used .5.
Anyway, this makes the XAML way more cluttered. Grid-designs (while I am using them myself) tend to get quite unwieldy.
I am not sure if this what you are looking for but my understanding of the question tells me you are talking about the label Value being away from the rest.
if you check the code for this label :
<Label Text="value" HorizontalOptions="End"></Label>
the HorizontalOptions is set to "End" which is causing this changing it to start will fix your problem
Feel free to revert in case if I missed anything
Goodluck