Multiple platform condition in XAML view - Xamarin forms [duplicate] - xamarin

I have the following C# code:
var footer = new StackLayout()
{ BackgroundColor = Device.OnPlatform(Color.FromRgb(225, 240, 251), Color.FromRgb(225, 240, 251), Color.Black),
};
How can I translate that into Xamarin Xaml, more importantly the Device Platform specifics for the FromRgb?
I have the following XAML so far... again, it's the FromRgb that's stumping me.
<StackLayout.BackgroundColor>
<Color>
<OnPlatform x:TypeArguments="Color"></OnPlatform>
</Color>
</StackLayout.BackgroundColor>
UPDATE 14/02/2015
I've just tried the answer below and I have the following but it's not updating the background colour for either iOS or Windows Phone. If I add the Background Color to the root StackLayout element it works...:
<StackLayout HorizontalOptions="FillAndExpand">
<StackLayout.BackgroundColor>
<Color>
<OnPlatform x:TypeArguments="Color">
<OnPlatform.WinPhone>#51C0D4</OnPlatform.WinPhone>
<OnPlatform.iOS>#51C0D4</OnPlatform.iOS>
</OnPlatform>
</Color>
</StackLayout.BackgroundColor>
<Label Text=""></Label>
<StackLayout Orientation="Horizontal" VerticalOptions="EndAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" HorizontalOptions="CenterAndExpand">
<Button Text="Login"></Button>
<Button Text="Sign Up"></Button>
</StackLayout>
</StackLayout>
</StackLayout>

You're almost there. The default converter takes care of converting the color from either a named color (e.g. White, Red, etc.) or a hex color (e.g.: #FF0000).
<StackLayout.BackgroundColor>
<OnPlatform x:TypeArguments="Color">
<OnPlatform.iOS>#FF0000</OnPlatform.iOS>
<OnPlatform.Android>#00FF00</OnPlatform.Android>
</OnPlatform>
</StackLayout.BackgroundColor>

Newer version syntax of OnPlatform is slightly different
In Xaml:
<ResourceDictionary>
<OnPlatform x:Key="SwitchOnColor" x:TypeArguments="Color" >
<On Platform="iOS|Android" >#0000FF</On>
<On Platform="UWP">#FF0000</On>
</OnPlatform>
</ResourceDictionary>
In code:
switch (Device.RuntimePlatform)
{
case "iOS":
break;
case "Android":
break;
case "UWP":
break;
default:
break;
}

You can do this also:
<ContentView>
<OnPlatform x:TypeArguments="View">
<On Platform="iOS">
<Label Text="iOS" />
</On>
<On Platform="Android">
<Label Text="Android" />
</On>
</OnPlatform>
</ContentView>

Related

Xamarin fontawesome icons displayed as square with x

After following some tutorials to include FontAwesome 5 Free in my Xamarin project it always ends up showing as a square with an x inside.
I think this is probably related to my xamarin.forms version (2.3.0.46-pre3) and i can't seem to make it work.
Here's the file names
Build action is set to AndroidAsset and copy if newer and BundleResource for IOS
Xaml where im using them
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TrainInURL.MainPage">
<Grid >
<Image Source="bg_home.png" VerticalOptions="Start" HorizontalOptions="Center"/>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand">
<StackLayout Orientation="Horizontal" Margin="10" Padding="10" >
<Label Text="Bienvenid#" TextColor="White" Font="Bold,16"></Label>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}"/>
</StackLayout>
<StackLayout Orientation="Vertical" HorizontalOptions="FillAndExpand" Margin="10" Padding="10" >
<Label x:Name="txt_Nombre" TextColor="White" Font="Bold,16"></Label>
<Label x:Name="txt_Apellido" TextColor="White" Font="Bold,16"></Label>
<Label x:Name="lblMensaje" HorizontalTextAlignment="Center"></Label>
</StackLayout>
<StackLayout >
</StackLayout>
</StackLayout>
</Grid>
</ContentPage>
App.xaml
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TrainInURL.App">
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="FontAwesomeSolid" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Solid"
Android="FontAwesomeSolid.ttf#Font Awesome 5 Free Solid" />
<OnPlatform x:Key="FontAwesomeRegular" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Regular"
Android="FontAwesomeRegular.ttf#Font Awesome 5 Free Regular" />
<OnPlatform x:Key="FontAwesomeBrands" x:TypeArguments="x:String"
iOS="Font Awesome 5 Free Brands"
Android="FontAwesomeBrands.ttf#Font Awesome 5 Free Brands" />
</ResourceDictionary>
<!-- Application resource dictionary -->
</Application.Resources>
</Application>
info.plist
<key>UIAppFonts</key>
<array>
<string>FontAwesomeSolid.ttf</string>
<string>FontAwesomeRegular.ttf</string>
<string>FontAwesomeBrands.ttf</string>
</array>
Is it even possible to use custom fonts with my version? Any help is welcomed
Update 1: Updated to version 2.5.1.527436, same issue
Update 2: Tried using a different font file, seems to indicate it can find the font but can't render it. Using the following font renderer gave the following results
CustomFontRenderer
[assembly: ExportRenderer(typeof(CustomFontLabel), typeof(CustomFontRenderer))]
namespace TrainInURL.Droid
{
public class CustomFontRenderer : LabelRenderer
{
public CustomFontRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
TextView label = (TextView) Control;
if (e.NewElement?.FontFamily != null)
{
Typeface font = null;
// the try-catch block will ensure the element is at least rendered with default
// system font in Xamarin Previewer instead of crashing the view
try
{
font = Typeface.CreateFromAsset(Android.App.Application.Context.Assets, e.NewElement.FontFamily);
}
catch (Exception)
{
font = Typeface.Default;
}
label.Typeface = font;
}
}
}
}
Xaml
<StackLayout Orientation="Horizontal" Margin="10" Padding="10" >
<Label Text="Bienvenid#" TextColor="White" FontSize="16" FontAttributes="Bold"></Label>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeSolid}"/>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeBrands}"/>
<Label Text="" TextColor="White" FontFamily="{StaticResource FontAwesomeRegular}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeSolid}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeBrands}"/>
<trainInUrl:CustomFontLabel Text="" FontFamily="{StaticResource FontAwesomeRegular}"/>
</StackLayout>
Result
I followed the instructions found here which got me started. there was also a bit of further tweaking to completely get it working (particularly UWP). I do note you are using the .ttf files and I am using the .otf files, which could be an issue.
My final final assets folder and resource implementation are below (android - no IOS here), hopefully helps you out.
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeBrands">
<On Platform="Android" Value="FontAwesome5Brands400.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Brands400.otf#Font Awesome 5 Brands"/>
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeSolid">
<On Platform="Android" Value="FontAwesome5Solid900.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Solid900.otf#Font Awesome 5 Free"/>
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FontAwesomeRegular">
<On Platform="Android" Value="FontAwesome5Regular400.otf#Regular"/>
<On Platform="UWP" Value="/Assets/Fonts/FontAwesome5Regular400.otf#Font Awesome 5 Free"/>
</OnPlatform>
</ResourceDictionary>
</Application.Resources>
Updated the app to version 4.4 and that solved the issue

How to properly set height on GRID?

I trying to create a UI something just like this (as a reference).
but I am having a trouble to get the design. I used grid but I keep getting this result. I set the Grid row definitions to 80* and 20* and still not getting the result I wanted. My idea is the design to be in percentage rather that set a specific height. If I can't use percentage is there a way to make my UI responsive for different screen size and orientation? Is there a way I can achieve this?
Here is my XAML Code:
<ContentPage.Content>
<ScrollView>
<StackLayout Spacing="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0" StyleClass="start" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label StyleClass="brand" Text="TBS">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Black.ttf#SFProDisplay-Black"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label StyleClass="startpagetitle" Text="TBS Point of Sale">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Light.ttf#SFProDisplay-Light"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label StyleClass="startpagesubtitle" Text="Run and grow your business.">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Light.ttf#SFProDisplay-Light"/>
</OnPlatform>
</Label.FontFamily>
</Label>
</StackLayout>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="0" BackgroundColor="White" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Button StyleClass="btn" Text="Login" x:Name="btnLogin">
<Button.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Regular.ttf#SFProDisplay-Regular"/>
</OnPlatform>
</Button.FontFamily>
</Button>
</StackLayout>
</Grid>
</StackLayout>
</ScrollView>
</ContentPage.Content>
Remove the StackLayout outside of your content Grid. The Grid won't take the whole space of the StackLayout so that it looks the percentage is wrong:
<ScrollView>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" Grid.Column="0" StyleClass="start" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<StackLayout VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand">
<Label StyleClass="brand" Text="TBS">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Black.ttf#SFProDisplay-Black"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label StyleClass="startpagetitle" Text="TBS Point of Sale">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Light.ttf#SFProDisplay-Light"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label StyleClass="startpagesubtitle" Text="Run and grow your business.">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Light.ttf#SFProDisplay-Light"/>
</OnPlatform>
</Label.FontFamily>
</Label>
</StackLayout>
</StackLayout>
<StackLayout Grid.Row="1" Grid.Column="0" BackgroundColor="White" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Button StyleClass="btn" Text="Login" x:Name="btnLogin">
<Button.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="SFProDisplay-Regular.ttf#SFProDisplay-Regular"/>
</OnPlatform>
</Button.FontFamily>
</Button>
</StackLayout>
</Grid>
</ScrollView>
Moreover, I think the scroll view can be removed too if you don't want your screen to scroll.
Or you can try to add <Grid VerticalOptions="FillAndExpand"> to make your Grid fill full of the StackLayout.

Align label and switch in xamarin forms

I want to align the label and switch in xamarin forms. I used grid but the label and switch wont align (see image for reference)
Here is my XAML:
<Grid>
<Label Grid.Row="0" Grid.Column="0" Text="Rekorida" StyleClass="lbl-fieldform">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="HelveticaNeueLTPro-Lt.otf#HelveticaNeueLTPro-Lt"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Switch Grid.Row="0" Grid.Column="1" VerticalOptions="Start" x:Name="swRekorida" Toggled="Activity_Toggled"/>
</Grid>
Use this:
<Grid VerticalOptions="Center">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Label VerticalTextAlignment="Center" Grid.Row="0" Grid.Column="0" Text="Rekorida" StyleClass="lbl-fieldform">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="HelveticaNeueLTPro-Lt.otf#HelveticaNeueLTPro-Lt"/>
</OnPlatform>
</Label.FontFamily>
</Label>
<Switch Grid.Row="0" Grid.Column="1" VerticalOptions="Center" x:Name="swRekorida" Toggled="Activity_Toggled"/>
</Grid>

Format button text and images in xamarin forms

I want to format text and the image like the image attached.
How can I center the text and put the image with a little padding on the left side to the side?
<Button StyleClass="btnFAF" Text="Field Activity" Image="icon.png" Grid.Row="0" Grid.Column="0" x:Name="btnFAF" Clicked="btnFAF_Clicked" BorderRadius="6">
<Button.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="OpenSans-Regular.ttf#OpenSans-Regular"/>
</OnPlatform>
</Button.FontFamily>
</Button>
Format I want
instead of a button, I would just compose the layout you want using a Layout control and attach a TapGestureRecognizer to it
I'll illustrate with nested StackLayouts, but this may be better suited to using a Grid instead
<StackLayout Orientation="Horizontal" >
<StackLayout.GestureRecognizers>
<TapGestureRecognizer Tapped="MyTappedHandler" />
<StackLayout.GestureRecognizers>
<Image ... />
<StackLayout>
<Label ... />
<Label ... />
</StackLayout>
</StackLayout>

Xamarin iOS images overlapping inside Grid

Heyo,
So in Xamarin I have a <Grid> with an <Image> and a couple <Label>s inside it, all wrapped inside a <ViewCell>. This looks totally fine in Xamarin.Android, however in Xamarin.iOS the images overlap the labels. I'm not sure what the difference could be - why does it look good in Xamarin.Android but in iOS its all wonky?
Below is my XAML and a couple mockups to show what I mean.
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Aspect="AspectFill" Source="{Binding ImageOverlayEN}" />
<Label Grid.Column="0" Grid.Row="1" VerticalTextAlignment="Start" LineBreakMode="WordWrap" Text="{Binding DynamicOfferText}" FontSize="18">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>RobotoCondensed-Regular</OnPlatform.iOS>
<OnPlatform.Android>RobotoCondensed-Regular.ttf#RobotoCondensed-Regular</OnPlatform.Android>
<OnPlatform.WinPhone>RobotoCondensed-Regular.ttf#RobotoCondensed</OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
<Label Grid.Column="0" Grid.Row="2" VerticalTextAlignment="Start" LineBreakMode="WordWrap" Text="{Binding DynamicOfferDetail}" FontSize="16">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<OnPlatform.iOS>RobotoCondensed-Regular</OnPlatform.iOS>
<OnPlatform.Android>RobotoCondensed-Regular.ttf#RobotoCondensed-Regular</OnPlatform.Android>
<OnPlatform.WinPhone>RobotoCondensed-Regular.ttf#RobotoCondensed</OnPlatform.WinPhone>
</OnPlatform>
</Label.FontFamily>
</Label>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
I tried setting the HeightRequest but that didn't seem to make a difference:
#if __IOS__
if (viewModel.Items.Count > 0)
{
MyListView.HeightRequest = 300 * viewModel.Items.Count;
}
#endif
Here is a visual representation of what is happening:
Figured it out - had to do with my RowDefinitions being all set to Auto
This got it looking just right:
<RowDefinition Height="1*" />
<RowDefinition Height="0.18*" />
<RowDefinition Height="0.77*" />
I think what was happening is the ListView renders first, the Auto row definition heights set the height of each row before the image is done loading, then the image finishes loading and overlaps the rest of the list view's item (including the labels). This might just be a quirk of iOS, where as Android calculates the row heights after the images are done loading (explaining why it looked fine in Android)

Resources