Displaying SVGs in Xamarin.Forms

June 3rd 2022 Xamarin

There is no built-in support for rendering SVG images in Xamarin.Forms, but there are a few NuGet packages you can use to add this functionality. Xamarin.Forms.Svg has worked well for me. It can create an ImageSource from an SVG so that it can be rendered by Image view just like other image formats.

I wanted to display a list of items with an image URL and a corresponding test in a ListView:

<ListView ItemsSource="{Binding Currencies}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Orientation="Horizontal">
                    <Image Source="{Binding LogoUrl}"/>
                    <Label Text="{Binding Symbol}"/>
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

This worked fine for bitmap images in PNG and JPG formats, but not for images in SVG format.

To fix this, I installed the Xamarin.Forms.Svg NuGet package in both the native projects and the shared .NET Standard project. I had to initialize the library in the native project as described in the official documentation:

  • In MainActivity.OnCreate for Android:

    Xamarin.Forms.Svg.Droid.SvgImage.Init(this);
    LoadApplication(new App());
    
  • In AppDelegate.FinishedLaunching for iOS:

    Xamarin.Forms.Svg.iOS.SvgImage.Init();
    LoadApplication(new App());
    

There are several ways to create an ImageSource from an SVG file. I decided to create a value converter that returns an SvgImageSource for SVG files and a normal ImageSource for other file formats:

public class UrlToImageSourceConverter : IValueConverter
{
    public object Convert(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        if (value is string)
        {
            var uriString = (string)value;
            Uri uri = new Uri(uriString);
            if (uri.AbsolutePath.ToLowerInvariant().EndsWith(".svg"))
            {
                return SvgImageSource.FromSvgUri(uriString, 200, 200, default(Color));
            }
            else
            {
                return ImageSource.FromUri(uri);
            }
        }
        else
        {
            return null;
        }
    }

    public object ConvertBack(
        object value,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

This allowed me to support the SVG file format with minimal impact on the rest of the code. I did not have to make any changes to the view model. Only in the view did I have to create a resource for the converter and use that in the Image binding:

<ContentPage.Resources>
    <converters:UrlToImageSourceConverter x:Key="ImageSrcConverter" />
</ContentPage.Resources>

<Image Source="{Binding LogoUrl, Converter={StaticResource ImageSrcConverter}}"/>

You can see the full code for the finished project in my GitHub repository.

Although Xamarin.Forms does not support SVG files out of the box, they can be easily rendered using the Xamarin.Forms.Svg NuGet package. I created a value converter that generates the correct image source for each image type: SvgImageSource from this NuGet package for SVG URLs and the default ImageSource for all other URLs. This way, no further code changes were required to add SVG support to the application.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Copyright
Creative Commons License