Creating a scalable Style Library in Xamarin Forms

About the topic:

Contenido

On more than one occasion we have used or copied the application styles previously created by you, your team, or the company to which it belongs within your new project. This is normal, especially if the styles created above are a kind of art work.

On other occasions, we may be forced to share styles within different applications. Here are some reasons:

  • You’re working with similar applications.
  • Apps are under the same brand.
  • Apps are related (such as uber, uber driver, uber eats, etc.)
  • You don’t want to create new styles, because the one you have already works well for you.
  • Etc…

All this is good until you start updating your styles and then you want to modify them in each project later. Regardless of, today you will learn how to create style libraries that you can share between projects and then customize in an amazing way.

So, let’s get to it!

Style library

A style library makes it easy to customize your designs in your applications so that the definition of your brand styles, support, and customization of colors, typography, and shapes are chords or constants throughout the application. This way we can provide a better user experience throughout your application.

⚠ Important

Previously, I had written an article that received a great reception by the community titled: «Taking the design of your applications to the next level with Xamarin Forms» Which I recommend you read if you have not.

What I need to create a style library

The first thing you’ll need to create a style library is to define how you want to structure or create your styles. A predefined naming convention can help a lot.

1. Before creating a style name you have to go to the base. Your styles will also be using resources that will need to be defined above if we want our library to be scalable.

💡 TIP

A clear example, which I really like to take as an example, is the Material Design library that defines Colors, fonts, shapes, and sizes as the basis, and then from these, styles are born.

2. Once you have the base defined then we can proceed to create the styles. Here is where you tell apps how you want your controls, views, and pages to look and behave.

3. When you already have your styles, you only have to apply them within your apps.

What you need to know before you create a style library

Later, let’s look at some ways in which you can create a style library within Xamarin Forms. But first, let’s refresh some concepts that need to be taken into account to create a style library.

⚠ Warning

The content and examples used in this article are with XAML. At the moment, it’s the only way to create the base, but you can still create your CSS styles if you want.

⚠ Warning

We will not abound or detail many in these concepts. As always, it is best to go to the official documentation to know the basis of Xamarin Forms components.

Explicit styles and implicit styles

Within Xamarin.Forms we can apply styles explicitly and implicitly. By way of summary:

  • Explicit when you apply styles to specific elements.
  • Implicit when you don’t apply it to specific elements but assign only the type of element.

Let’s look at an example:

...
            <!-- EXPLICIT -->
            <Style x:Key="labelRedStyle" TargetType="Label">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="FontSize" Value="Large" />
                <Setter Property="TextColor" Value="Red" />
            </Style>

            <!-- IMPLICIT -->
            <Style TargetType="Entry">
                <Setter Property="HorizontalOptions" Value="Fill" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
                <Setter Property="BackgroundColor" Value="Yellow" />
                <Setter Property="FontAttributes" Value="Italic" />
                <Setter Property="TextColor" Value="Blue" />
            </Style>
...

Learn more about explicit styles here, and about the implicit styles here.

Override styles

Don’t forget that you can always override or modify your styles. Lower styles in the view hierarchy take precedence over those defined above.

Let’s look at an example:

...
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style x:Key="buttonStyle" TargetType="Button">
                ...
                <Setter Property="TextColor" Value="Red" />
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

   <ContentPage.Content>
        <StackLayout Padding="0,20,0,0">
            <StackLayout.Resources>
                <ResourceDictionary>
                    <Style x:Key="buttonStyle" TargetType="Button">
                        ...
                        <Setter Property="TextColor" Value="Blue" />
                    </Style>
                </ResourceDictionary>
            </StackLayout.Resources>

            <Button Text="These buttons" Style="{StaticResource buttonStyle}" />
            <Button Text="are demonstrating" Style="{StaticResource buttonStyle}" />
            <Button Text="application style overrides" Style="{StaticResource buttonStyle}" />
        </StackLayout>
    </ContentPage.Content>
...

In this example, we set a style on our page (top-level style) where a button is set with red text, but within our StackLayout, we set a style (lower-level style) where a button with the blue text is set.

The style that is applied is the lower-level style. Therefore, the text of the buttons will be BLUE. Learn more here.

Style inheritance

Style inheritance will help us create a style library as it will help us reuse, extend, or modify the behavior of our styles.

Style inheritance in Xamarin Forms is used by setting our BasedOn property to the reference of a previously created style.

Let’s look at an example:

...
            <Style x:Key="baseStyle" TargetType="View">
                <Setter Property="HorizontalOptions" Value="Center" />
                <Setter Property="VerticalOptions" Value="CenterAndExpand" />
            </Style>
...
            <Style x:Key="labelStyle" TargetType="Label"
                   BasedOn="{StaticResource baseStyle}">
                ...
                <Setter Property="TextColor" Value="Teal" />
            </Style>
...

Learn more about style inheritance here.

Style classes

Style classes allow us to apply multiple styles to control, without having to resort to style inheritance. This suits us especially well when we want to create multiple class styles that we want to share in some controls but maybe not in others.

Let’s look at an example:

...
        <Style TargetType="BoxView" Class="Separator">
            <Setter Property="BackgroundColor" Value="#CCCCCC" />
            ...
        </Style>

        <Style TargetType="BoxView" Class="Rounded">
            <Setter Property="BackgroundColor" Value="#1FAECE" />
            ...
        </Style>    

        <Style TargetType="BoxView" Class="Circle">
            <Setter Property="BackgroundColor" Value="#1FAECE" />
            ...
            <Setter Property="CornerRadius" Value="50" />
        </Style>

        <Style TargetType="VisualElement" Class="Rotated" ApplyToDerivedTypes="true">
            <Setter Property="Rotation" Value="45" />
        </Style> 
...
...
        <BoxView StyleClass="Separator" />       
        <BoxView StyleClass="Rounded, Rotated" />
        <BoxView StyleClass="Circle" />
...

Learn more about style classes here.

Merged resource dictionaries

One thing that can help you better structure and define your styles are resource dictionaries, especially when you merge them.

Let’s look at an example:

<ContentPage ...
             xmlns:local="clr-namespace:ResourceDictionaryDemo"
             xmlns:theme="clr-namespace:MyThemes;assembly=MyThemes">
    <ContentPage.Resources>
        <ResourceDictionary>
            ...
            <ResourceDictionary.MergedDictionaries>
                ...
                <local:MyResourceDictionary />
                <theme:LightTheme />
                ...
            </ResourceDictionary.MergedDictionaries>
            ...
        </ResourceDictionary>
    </ContentPage.Resources>
    ...
</ContentPage>

Learn more about the merged styles here.

Strategies for creating a library of styles

1. Create a library within the project and then copy it to the others

The most common way is to have one or more projects from which we feed our styles within new projects. And this is fine until you see that you modify/improve your styles and want to update the styles in all projects.

Many times, it can even be a little confusing to remember where it is what you are looking for and it wastes a little time in the process.

ℹ Important

I know copy/paste is legendary, but if you want to know how to create a library of scalable styles keep reading.

2. Create a style library in a shared project

The next step, as you’ll understand, is to create a shared project and within it put all your styles or resource dictionaries. Once you have your shared style library, the next step is to combine our styles within our new project.

And with this, I’d be, you’d have all your styles combined within the new project.

💡 TIP

Remember that you can always replace styles using the same names of our resources as we saw above. With this, you can adapt your styles to new projects.

So far, following good practices, everything would be fine with the truth. But we have the detail that we need to know what styles we have to configure, create them, and then adapt them to our project.

In most cases, this wouldn’t be a problem but if you want to create a library that can be scaled even further, read on.

3. Create a style library that can be configured between projects

I really liked the XF-Material-Library because of how they manage and configure their resources. This library has two things that I love that are: the structure of the material design and the way they configure their resources.

Let’s look at an example:

...
    <Application.Resources>
        ...
        <mtrl:MaterialColorConfiguration x:Key="Material.Color"
            Background="#EAEAEA"
            Error="#B00020"
            OnBackground="#000000"
            OnError="#FFFFFF"
            OnPrimary="#FFFFFF"
            OnSecondary="#FFFFFF"
            OnSurface="#000000"
            Primary="#011A27"
            PrimaryVariant="#000000"
            Secondary="#063852"
            SecondaryVariant="#001229"
            Surface="#FFFFFF" />
        ...
    </Application.Resources>
...

As you can see they create an object where we pass all our settings and then add or combine them to the styles that the new project uses.

With this, we easily avoid typo errors and at the same time keep our shared library very clean and scalable. And of course, we have all the above advantages if necessary.

How to create a style library that can be configured between projects

The first thing we have to do is create our configuration files, which are just classes that derive from BindableObject and have all the configuration properties that we’re going to be using.

Let’s look at an example:

...
   public sealed class ColorConfiguration : BindableObject
   {
        ...
        public static readonly BindableProperty BackgroundProperty = BindableProperty.Create(nameof(Background), typeof(Color), typeof(Color), Color.FromHex("#EAEAEA"));

        public Color Background
        {
            get => (Color)GetValue(BackgroundProperty);
            set => SetValue(BackgroundProperty, value);
        }
        ...
    }
...

You must also add a configuration class that has all the settings of your styles. Let’s look at an example:

...
   public sealed class StyleConfiguration : BindableObject
   {
        ...
        public static readonly BindableProperty ColorConfigurationProperty = BindableProperty.Create(nameof(ColorConfiguration), typeof(ColorConfiguration), typeof(ColorConfiguration));

        public ColorConfiguration ColorConfiguration
        {
            get => (ColorConfiguration)GetValue(BackgroundProperty);
            set => SetValue(BackgroundProperty, value);
        }
        ...
    }
...

Once you have your configuration file, the next step is to create your resource dictionary where you’re adding your resources.

Let’s look at an example:

...
    public partial class Colors : ResourceDictionary
    {
       internal Colors(ColorConfiguration colorConfiguration)
       {
            Add("BackgroundColor", colorConfiguration.Background);
       }
    }
...

Once you have your resource dictionary for configurations, the next step is to create the styles we’ll be using in your project.

<ResourceDictionary ... >
    ...
    <Style Class="H1" TargetType="Label">
        ...
    </Style>
    ...
</ResourceDictionary>

Well, so far everything is excellent. We would only need a mechanism to combine styles. Here’s an example:

...
    public class ProjectStyle
    {
        private ResourceDictionary _resources;

        internal ProjectStyle(Application app, StyleConfiguration config = null)
        {
            app.Resources.MergedDictionaries.Add(new Colors(config.ColorConfiguration));
            
            // MERGE YOUR PREDEFINED STYLES HERE
            app.Resources.MergedDictionaries.Add(new MyStyle());
        }

        public static void Init(Application app, StyleConfiguration config)
        {
            new ProjectStyle(app, config);
        }
...

Once we have our initiation class complete, we just need to initialize our styles. Let’s look at the example:

...
    <Application.Resources>
        ...
        <st:ColorConfiguration x:Key="Style.Color" Background="#EAEAEA" />
        <st:MaterialConfiguration x:Key="Style.Configuration" ColorConfiguration="{StaticResource Style.Color}"  />
        ...
    </Application.Resources>
...

💡 TIP

You can also initialize these objects in your App.xaml.cs

...
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            ProjectStyle.Init(this); // Use default styles

            MainPage = new MainPage();
        }
...

And with this, we would already have our style library completed and configured to be used in any project.

Well, I’ll give you an example with a slightly more defined implementation based on the XF-Material-Library library. Unlock the content below to access the sample repo.

Conclusion

As you could see, here I have given you some strategies to create a library of styles that you can use between projects of the way in which you create that best suits your needs.

I hope this article is useful, and nothing let me know on my social media and if you really like these kinds of articles and I will do my best to give them the best of the best.

With nothing else to add, see you next time!

What do you think of this content?
 
Luis Matos

Luis Matos

I help professionals and companies to create value solutions. I am a Systems Engineer, blockchain executive, and international mobile application speaker. Founder of the Malla Consulting Agency and several international technology communities.
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x

Search in the site