Shell FlyoutItem icon from Font Awesome

2.2k Views Asked by At

I am trying to use FontAwesome icons in FlyoutItem as an icon using FontImageSource. I had success in Xamarin Forms with following setup, but for some reason in NET MAUI it does not work (at least on Windows?)? I am seeing tab item, but there is no icon no matter what I try. Is there some way to use Font Awesome icons instead of png pictures?

Example of icon I am trying to use: https://fontawesome.com/icons/user?s=solid&f=classic

MauiProgram.cs:

var builder = MauiApp.CreateBuilder();
builder
  .UseSkiaSharp(true)
  .UseMauiApp<App>()
  .ConfigureFonts(fonts =>
  {
    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
    fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
    fonts.AddFont("FW-Regular-400.otf", "FontAwesomeRegular");
    fonts.AddFont("FWBrands-Regular-400.otf", "FontAwesomeBrands");
    fonts.AddFont("FW-Solid-900.otf", "FontAwesomeSolid");
  });

App.xaml:

  <!-- Desktop/Tablet-->
  <FlyoutItem Title="Home">
    <ShellContent ContentTemplate="{DataTemplate page:HomePage}">
      <ShellContent.Icon>
        <FontImageSource FontFamily="FontAwesomeSolid" Glyph="&#xf021;"/>
      </ShellContent.Icon>
    </ShellContent>
  </FlyoutItem>
  <FlyoutItem Title="Settings">
    <ShellContent ContentTemplate="{DataTemplate page:SettingsPage}">
      <ShellContent.Icon>
        <FontImageSource FontFamily="FontAwesomeSolid" Glyph="user"/>
      </ShellContent.Icon>
    </ShellContent>
  </FlyoutItem>

enter image description here enter image description here

3

There are 3 best solutions below

7
On BEST ANSWER

I have got it working way mentioned below. However currently it seems that this solution is working in NET7, but not in NET6. In NET6 there are no icons visible:

enter image description here


For NET 7

App.xaml:

<?xml version = "1.0" encoding = "UTF-8" ?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:MyTool"
             xmlns:page="clr-namespace:MyTool.Pages"
             xmlns:helpers="clr-namespace:MyTool.Helpers"
             x:Class="MyTool.App">

  <Application.MainPage>
    <Shell FlyoutWidth="90" FlyoutBehavior="{OnIdiom Phone=Disabled, Default=Locked}">

      <!-- Desktop/Tablet-->
      <FlyoutItem Title="Home" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.House}, Size=50}">
        <ShellContent ContentTemplate="{DataTemplate page:HomePage}">
          <ShellContent.Icon>
            <FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.House}" Color="White" Size="50"/>
          </ShellContent.Icon>
        </ShellContent>
      </FlyoutItem>
      <FlyoutItem Title="Settings" Icon="{FontImage FontFamily=FontAwesomeSolid, Glyph={x:Static helpers:FontAwesomeIcons.Gear}, Size=50}">
        <ShellContent ContentTemplate="{DataTemplate page:SettingsPage}">
          <ShellContent.Icon>
            <FontImageSource FontFamily="FontAwesomeSolid" Glyph="{x:Static helpers:FontAwesomeIcons.Gear}" Color="White" Size="50"/>
          </ShellContent.Icon>
        </ShellContent>
      </FlyoutItem>
    </Shell>
  </Application.MainPage>
</Application>

FontAwesomeIcons.cs: (use some tool available in Internet for such a class generation)

namespace MyTool.Helpers
{
    public static class FontAwesomeIcons
    {
      public const string Space = "\u0020";
      public const string Exclamation = "\u0021";
      public const string Hashtag = "\u0023";
      public const string DollarSign = "\u0024";
      public const string Percent = "\u0025";
      public const string Asterisk = "\u002a";
      public const string Plus = "\u002b";
      public const string Hyphen = "\u002d";

      // etc
    }
 }

MauiProgram.cs:

namespace MyTool;

public static class MauiProgram
{
  public static MauiApp CreateMauiApp()
  {
    var builder = MauiApp.CreateBuilder();
    builder
      .UseMauiApp<App>()
      .ConfigureFonts(fonts =>
      {
        fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
        fonts.AddFont("FW-Solid-900.otf", "FontAwesomeSolid");
      });

#if DEBUG
    builder.Logging.AddDebug();
#endif

    return builder.Build();
  }
}
0
On

The easy solution works for me:

    <FlyoutItem
       Title="Dalle Chalange"
       Icon="{FontImage FontFamily=fontello, 
       Glyph={x:Static FontIcons:IconFont.Compass}, 
       Color=White,
       Size=30}">
       <ShellContent
          ContentTemplate="{DataTemplate dalle_views:DashboardView}" />
</FlyoutItem>

EDIT: Here is same approach but better:

<FlyoutItem Title="Dalle Chalange">
    <FlyoutItem.FlyoutIcon>
        <FontImageSource
            FontFamily="fontello"
            Glyph="{x:Static FontIcons:IconFont.Compass}"
            Color="{AppThemeBinding Light={StaticResource light_onSurface}, Dark={StaticResource dark_onSurface}}"/>
    </FlyoutItem.FlyoutIcon>
    <ShellContent
        ContentTemplate="{DataTemplate dalle_views:DashboardView}" />

</FlyoutItem>
0
On

To be added as an answer to Shell FlyoutItem icon from Font Awesome

Here's one that works for me. The difference to @10101's answer, and to the one I had above that didn't work is the definition of a static FontIcon resource.
Tested on Net6 and Net7 (VS2022 17.4.4).

It is based on @10101's answer combined with an idea here.

Steps

  • Added a FontIcon resource.
  • Set the Icon property on the FlyoutItem (as opposed to the underlying ShellContent).

Limitation: the size and color are set on the FontImage resource in the resource definition, not where it is used in FlyoutItem definition. I don't know how to override those properties on the FlyoutItem.

Code
Font registration in MauiProgram.cs (abbreviated):

public static MauiApp CreateMauiApp()
    {
        var builder = MauiApp.CreateBuilder();
        builder
            .UseMauiApp<App>()
            .ConfigureFonts(fonts =>
            {
                [...]
                // Custom fonts
                fonts.AddFont("bootstrap-icons.ttf", "Bootstrap");
            });

            [...]
            return builder.Build();
        }

FontIcon created as a resource in styles.xaml (I actually created another resource definition file called fonticons.xaml and added to the merged resource dictionary in App.xaml, but this is not important in this case):

<ResourceDictionary 
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">

    <x:String x:Key="BootStrapGear">&#xf3e5;</x:String>

    <FontImage x:Key="IconGear"
        FontFamily="Bootstrap"
        Color="Black"
        Size="50"
        Glyph="{x:StaticResource BootStrapGear}"/>
</ResourceDictionary>

AppShell.xaml:

<Shell
    x:Class="MyApp.AppShell"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    [...]
    Shell.FlyoutBehavior="Flyout">
 
    [...]
    <FlyoutItem Title="Settings" Icon="{x:StaticResource IconGear}">
        <ShellContent
            ContentTemplate="{DataTemplate localconfigns:ConfigPage}"
            Route="ConfigPage" />
    </FlyoutItem>
</Shell>