How do I set the font in a StaticResource? - xaml

I'm trying to define the FontAwesome fontFamily in the App.xaml so I can use staticresource in my code.
Setting the fontFamily directly in the page is working. Problem is when I try to get this value from the StaticResource I have a blank page showing.
App.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<prism:PrismApplication xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Unity;assembly=Prism.Unity.Forms"
x:Class="RedPrairie.App">
<Application.Resources>
<!-- Application resource dictionary -->
<ResourceDictionary>
<!-- Font Awesome fonts path per plateform -->
<OnPlatform x:Key="FontAwesomeBrands" x:TypeArguments="x:String" Android="FontAwesome5Brands.otf#Font Awesome 5 Brands Regular" iOS="Font Awesome 5 Free" />
<OnPlatform x:Key="FontAwesomeSolid" x:TypeArguments="x:String" Android="FontAwesome5Solid.otf#Font Awesome 5 Free Solid" iOS="Font Awesome 5 Free" />
<OnPlatform x:Key="FontAwesomeRegular" x:TypeArguments="x:String" Android="FontAwesome5Regular.otf#Font Awesome 5 Free Regular" iOS="Font Awesome 5 Free" />
</ResourceDictionary>
</Application.Resources>
</prism:PrismApplication>
My Page:
<Label Text="{x:Static model:Icon.far_user}"
FontFamily="{StaticResource FontAwesomeRegular}"
FontSize="Large"
TextColor="SkyBlue"
VerticalOptions="Center">
</Label>
working Page :
<Label Text="{x:Static model:Icon.far_user}"
FontSize="Large"
TextColor="SkyBlue"
VerticalOptions="Center">
<Label.FontFamily>
<OnPlatform
x:TypeArguments="x:String"
Android="FontAwesome5Regular.otf#Font Awesome 5 Free Regular"
iOS="Font Awesome 5 Free" />
</Label.FontFamily>
</Label>
Another working Page :
<Label Text=""
FontSize="Large"
TextColor="SkyBlue"
VerticalOptions="Center">
<Label.FontFamily>
<OnPlatform
x:TypeArguments="x:String"
Android="FontAwesome5Regular.otf#Font Awesome 5 Free Regular"
iOS="Font Awesome 5 Free" />
</Label.FontFamily>
</Label>
Content of class Icon :
public static class Icon
{
/*Regular Icons - prefixed with FAR_*/
public static string far_address_book = "\uf2b9";
public static string far_address_card = "\uf2bb";
public static string far_angry = "\uf556";
public static string far_arrow_alt_circle_down = "\uf358";
public static string far_arrow_alt_circle_left = "\uf359";
public static string far_arrow_alt_circle_right = "\uf35a";
public static string far_arrow_alt_circle_up = "\uf35b";
public static string far_user = "\uf007";
...
}
What am I doing wrong here?

Simplify the font filename and use font names as shown below.
It seems that Android is not strict on the font name, however, if the font filename is incorrect a RuntimeException: 'Font asset not found ' is thrown.
On iOS, if the font filename is incorrect in the UIAppFonts array key in Info.plist, or the font name is incorrect, the glyph/text appears as a question mark within a frame.
On UWP, with an incorrect font filename or font family name, the glyph/text appears just as a frame.
Font file location and content type in project:
iOS: Font file location: Resources folder. Content type: BundleResource
Android: Font file location: Assets folder. Content type: AndroidAsset
UWP: Font file location: Assets folder. Content type: Content
ResourceDictionary:
<OnPlatform x:TypeArguments="x:String" x:Key="FaRegular">
<On Platform="iOS" Value="FontAwesome5Free-Regular" />
<On Platform="Android" Value="FontAwesome5Regular.otf#Font Awesome Regular" />
<On Platform="UWP" Value="Assets/FontAwesome5Regular.otf#Font Awesome 5 Free" />
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FaSolid">
<On Platform="iOS" Value="FontAwesome5Free-Solid" />
<On Platform="Android" Value="FontAwesome5Solid.otf#Font Awesome Solid" />
<On Platform="UWP" Value="Assets/FontAwesome5Solid.otf#Font Awesome 5 Free" />
</OnPlatform>
<OnPlatform x:TypeArguments="x:String" x:Key="FaBrands">
<On Platform="iOS" Value="FontAwesome5Brands-Regular" />
<On Platform="Android" Value="FontAwesome5Brands.otf#Font Awesome Brands" />
<On Platform="UWP" Value="Assets/FontAwesome5 Brands.otf#Font Awesome 5 Brands" />
</OnPlatform>
Example Label:
<Label Text="" TextColor="Accent" FontFamily="{StaticResource FaRegular}" />
<Label Text="" TextColor="Accent" FontFamily="{StaticResource FaSolid}" />
<Label Text="" TextColor="Accent" FontFamily="{StaticResource FaBrands}" />
For iOS add the following using Open With > XML editor in Info.plist:
<key>UIAppFonts</key>
<array>
<string>FontAwesome5Brands.otf</string>
<string>FontAwesome5Regular.otf</string>
<string>FontAwesome5Solid.otf</string>
</array>

Related

Xamarin.Forms DynamicResource doesn't seem to be working

I can't seem to get a DynamicResource working correctly.
Here's the XAML in App.xml:
<Application.Resources>
<ResourceDictionary>
<Thickness x:Key ="DefaultInsets"
Bottom="4"
Top ="4"
Left ="8"
Right ="8" />
</ResourceDictionary>
</Application.Resources>
And here's what I'm trying to do inside another file's ContentView:
<StackLayout
VerticalOptions="Center"
HeightRequest="225"
Margin="{DynamicResource DefaultInsets}" >
<Entry
x:Name="nameControl"
Placeholder="Full Name"
Margin="{DynamicResource DefaultInsets}"
/>
<Entry
x:Name="passwordControl"
IsPassword="True"
Placeholder="Password"
Margin="{DynamicResource DefaultInsets}" />
</StackLayout>
It seems like this should make consistent insets for the StackLayout from the ContentView, and for the Entry fields from the StackLayout. But I don't see any of that.
What have I done wrong?
Update : I have also tried this with StaticResource, and still no luck.
I use following type with ResourceDictionary. For distinguish, I set the top_margin to 40, here is my screenshot.
Here is my ResourceDictionary.
<Application.Resources>
<ResourceDictionary>
<OnPlatform x:Key="OuterPadding" x:TypeArguments="Thickness">
<On Platform="Android">8 ,40,8,4</On>
<On Platform="iOS">20</On>
<On Platform="WinPhone">24</On>
</OnPlatform>
<!-- left, top, right, and bottom-->
</ResourceDictionary>
</Application.Resources>
Here is my layout.
<StackLayout
VerticalOptions="Center"
HeightRequest="225"
Margin="{DynamicResource OuterMargin}" >
<Entry
x:Name="nameControl"
Placeholder="Full Name"
Margin="{DynamicResource OuterMargin}"
/>
<Entry
x:Name="passwordControl"
IsPassword="True"
Placeholder="Password"
Margin="{DynamicResource OuterMargin}" />
</StackLayout>
Update
I found you layout issue is related to the VerticalOptions="Center" in the StackLayout(If you set the VerticalOptions="Center", then set the margin value is not work).
If I delete it and use StaticResource.
Here is running screenshot(For testing, I change the value of margin top to 20)
Other answers may be valid for some people, but in the end here's what I was doing wrong:
InitializeComponent() was never getting called inside App.xaml.cs.
I had an if-then statement that was always hitting a return before ever getting to InitializeComponent().
When that doesn't get called, App.xaml is inaccessible to the rest of the app, and nothing defined there is available as a DynamicResource.
So I moved InitializeComponent() to happen before the if-then statement, and now it all works like gangbusters.
I hope this helps someone!

Using Font Awesome on Xamarin App shows blank box instead of the icon on UWP

I'm using Font Awesome 5 in my xamarin app. I would like to show an icon in a RadButton (Telerik):
<telerikInput:RadButton
Grid.Row="0" Grid.Column="0"
Text=""
FontSize="30"
Style="{StaticResource TelerikButtonStyle}"
Command="{Binding MyCommand}">
<telerikInput:RadButton.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="Android" Value="FontAwesome5Free-Solid-900.otf#Font Awesome 5 Free Solid" />
<On Platform="Windows" Value="Assets/Fonts/FontAwesome5Free-Solid-900.otf#Font Awesome 5 Free Solid" />
</OnPlatform>
</telerikInput:RadButton.FontFamily>
</telerikInput:RadButton>`
For Android, this works fine, but in UWP it shows a blank box.
On Platform should be using "UWP" instead of the ""Windows""
<On Platform="UWP" Value="Assets/Fonts/FontAwesome5Free-Solid-900.otf#Font Awesome 5 Free Solid" />
Font Awesome does not contain Solid in the Font Name. Try removing Solid from the name as below:
<On Platform="Windows" Value="Assets/Fonts/FontAwesome5Free-Solid-900.otf#Font Awesome 5 Free" />
EDIT:
If you are using Xamarin.Forms 2.3.4 or greater than replace Windows with UWP as below:
<On Platform="UWP" Value="Assets/Fonts/FontAwesome5Free-Solid-900.otf#Font Awesome 5 Free" />
I have tried this in blank solution and got it working as follows:
Added the font in the Assets/Fonts folder in UWP project and made sure it has the correct name (in my case I renamed the font to FontAwesome5.otf) and Build Action of Content:
Used the following to reference the font (note - this sample only sets UWP path, so you should add the other platforms as in your question):
XAML:
<Label Text=""
FontSize="40"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand">
<Label.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="UWP" Value="Assets/Fonts/FontAwesome5.otf#Font Awesome 5 Free" />
</OnPlatform>
</Label.FontFamily>
</Label>
The proper # suffix can be found out using some font viewer apps, like dp4 Font Viewer:
Result:

New OnPlatform/OnIdiom XAML Extension - Usage for Margin Thickness

In Xamarin.Forms 3.2.0, Xamarin Forms introduced new New OnPlatform/OnIdiom XAML Extension
As per the blog we can re-write the below code,
<Button Text="Extensions" BackgroundColor="Black" TextColor="White">
<Button.HeightRequest>
<OnPlatform x:TypeArguments="x:Double" Default="40">
<On Platform="iOS" Value="60"/>
<On Platform="Android" Value="80"/>
</OnPlatform>
</Button.HeightRequest>
with the new extension.
<Button Text="Extensions" BackgroundColor="Black" TextColor="White"
HeightRequest="{OnPlatform iOS=60, Android=80, Default=40}"/>
Here my doubt is how I can reuse the same OnIdiom XAML Extension for Margin / Thickness.
You should be able to do it like this: <Button Margin="{OnPlatform Android='10,5,10,0', iOS='10,20,10,0'}" />
It's up to you which syntax you like more!

Use resource file in XAML file (Xamarin)

How to use resource files in XAML (xamarin forms) like <Label Text="MyApp.resouces.MyString" />?
There is a nice article here covering this topic. It includes lot of examples.
After you implement your TranslateExtension your code will look like this:
<Label x:Name="lblName" Text="{local:TranslateExtension MyString}" />
Your App.axml file:
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Master.App">
<Application.Resources>
<!-- Application resource dictionary -->
<ResourceDictionary>
<x:String x:Key="AppName">Name of app</x:String>
</ResourceDictionary>
</Application.Resources>
</Application>
And then your label:
<Label Text="{StaticResource AppName}"/>

How to change ListView selected item's background color?

My ListView structure in xaml file is written below. In this listview, I am adding some list items. When I click on any item from this items the background color of selected item will be orange by default. I wish this selected iem's background to be black. How can I achieve this in xaml?
<ListView x:Name="LstMenu"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical">
<StackLayout Orientation="Vertical"`enter code here`
Padding="10">
<Label Text="{Binding ListItems}"
FontSize="15"
TextColor="White"
HorizontalTextAlignment="Start"
VerticalTextAlignment="Center" />
</StackLayout>
<Grid BackgroundColor="Black"
HeightRequest="1"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I really wish there was a great cross-platform solution to this issue, but to date I haven't found one. Here's a link to a nearly identical question from the Xamarin.Forms Forums. Using an Android project as an example, I typically achieve the effect you are looking for by adding a styles.xml file to the Resources directory:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<color name="CustomHighlight">#android:color/transparent</color>
<style name="Theme.Splash" parent="android:Theme">
<item name="android:windowBackground">#drawable/androidsplash</item> <!-- must be lowercase -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowIsFloating">false</item>
<item name="android:backgroundDimEnabled">true</item>
</style>
<style name="CustomTheme" parent="android:Theme.Holo">
<item name="android:icon">#android:color/transparent</item>
<item name="android:colorPressedHighlight">#color/CustomHighlight</item>
<item name="android:colorLongPressedHighlight">#color/CustomHighlight</item>
<item name="android:colorFocusedHighlight">#color/CustomHighlight</item>
<item name="android:colorActivatedHighlight">#color/CustomHighlight</item>
<item name="android:activatedBackgroundIndicator">#color/CustomHighlight</item>
<!--<item name="android:colorActivatedHighlight">#android:color/transparent</item>-->
</style>
<style name="ProgressBarStyle" parent="#android:style/Widget.ProgressBar.Horizontal"/>
</resources>
Note that I am using a sytem defined color (transparent) in this case, but you could reference or define any color you like.Then add a reference to the style in your MainActivity.cs file:
[Activity(Label = Constants.CompanyName,
Theme = "#style/CustomTheme",
Icon = "#drawable/icon",
MainLauncher = false,
ScreenOrientation = ScreenOrientation.Portrait,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
// your code here
}
I don't have a handy sample for Windows or iOS, but the concept is the same; override a default style in the platform specific project.