Establishing Global Font Styles in a Flutter Project: Insights from the Xela Design System
Tags: flutter, webdev, programming, tutorial
Published: 2023-07-27 20:40:45

Hello, fellow Flutter enthusiasts! The role of fonts in your application's visual consistency and user interface experience is indispensable. They not only relay information but also set the tone and mood of your application. However, handling these styles can become an intricate task, particularly in large-scale projects.

In this article, we will examine how to construct global font styles in Flutter. This approach ensures uniformity across your application, makes your design more appealing, and significantly accelerates your development workflow. We will share insights from our experience of developing the Xela Design System, a unique library packed with a plethora of ready-to-use components, inclusive of font styles.

We aim to demonstrate how we exploited Flutter's capabilities to devise scalable, adaptable, and effortlessly customizable font styles in the Xela Design System. Follow along as we take you through the step-by-step process of this venture.

**Step 1: Setting Up a Flutter Project in Android Studio**

The first step in our endeavor is to establish a new Flutter project. If you've already dabbled in Flutter and Android Studio, this process should be straightforward. If you're a Flutter novice, fret not, we will walk you through all the necessary steps.

1. **Launch Android Studio**: Ensure you have the latest versions of Android Studio and the Flutter plugin installed. If you don't, you can procure them from the official [Android Studio](https://developer.android.com/studio) and [Flutter](https://flutter.dev/) websites.

2. **Initiate a new Flutter project**: Navigate to `File -> New -> New Flutter Project`.

3. **Select the type of project**: In the ensuing window, opt for `Flutter Application` and click `Next`.

4. **Configure the project details**: Fill out the necessary fields, including the project name, its location, and a brief description. Then, select the Flutter SDK version you wish to use (if you have multiple versions installed).

5. **Choose a package name for your project**: The subsequent step involves selecting your project's package name. This is conventionally the reverse URL of your website, but you can select any unique name.

6. **Wrap up**: Click `Finish`, and Android Studio will construct a new Flutter project for you.

Now, you're equipped with a new Flutter project, primed for further adjustments and development. In the next segment, we'll delve into how to start integrating font styles into your new project.

**Step 2: Establishing a uikit Directory within the lib Folder**

Our next move is to create an organized directory structure for our project. Effectively managing the files and directories within a project is integral to smooth and efficient development. Let's create a folder named `uikit`, which will serve as the home for our custom styles and UI components.

1. **Access the lib directory**: In the left panel of Android Studio, you will find the `lib` directory. This directory holds the primary code of your Flutter application.

2. **Generate a new directory**: Right-click on the `lib` directory and then navigate to `New -> Directory`. Input `uikit` as the name for your new directory.

You now have a `uikit` directory nested within your project's `lib` directory. This will be our base for UI styles and components. In the upcoming steps, we'll begin populating it with our font styles.

**Step 3: Creating a text_style.dart Dart File**

Now that we've got our `uikit` folder all set up, it's time to create a Dart file that will hold our font styles. We'll name this file `text_style.dart`.

1. **Navigate to the uikit folder**: Click on the `uikit` folder that we established in the previous step.

2. **Generate a new Dart file**: Right-click on the `uikit` folder, then select `New -> Dart File`. Input `text_style` as the name for this new file.

You've now got a `text_style.dart` file nestled within the `uikit` folder. This will be the file where we lay out our font styles. In the steps that follow, we'll begin adding code for our font styles.

**Step 4: Importing Flutter's Material Package and Creating XelaTextStyle Class**

With our `text_style.dart` file ready to go, let's get started with our coding process. We'll kick things off by importing Flutter's Material package, which provides a myriad of useful widgets and styles, and then create our `XelaTextStyle` class to house our font styles.

Incorporate the following code into `text_style.dart`:

```dart
import 'package:flutter/material.dart';

class XelaTextStyle {
  // Future home of our font styles
}
```

The code above starts by importing Flutter's `material.dart` library, a fundamental part of Flutter that provides a range of widgets and functionalities for app development. Following this, we declare a new class `XelaTextStyle` which will accommodate our font styles.

In the next step, we'll begin defining specific font styles within our `XelaTextStyle` class.

**Step 5: Introducing the XelaTextStyle._() Constructor**

Let's further refine our `XelaTextStyle` class by adding a private named constructor `XelaTextStyle._()`. This constructor ensures that our class cannot be instantiated or extended, essentially turning it into a "static" class.

Modify your code as follows:

```dart
import 'package:flutter/material.dart';

class XelaTextStyle {
  XelaTextStyle._();  // The newly added private constructor

  // Font styles will be defined here
}
```

In the above snippet, we've added `XelaTextStyle._();` to our class. This is a private named constructor, preventing the creation of instances of our `XelaTextStyle` class. This ensures that the class remains "static", with only static members (in this case, text styles) and no capability to create an instance of the class.

This approach is advantageous for grouping and organizing code, particularly for styles and templates that you'll reuse throughout your app without needing to instantiate the class each time.

**Step 6: Integrating a Custom Font into Your Project**

In most design undertakings, you'll likely encounter a need to use custom fonts. For our case, we'll be incorporating the `Nunito Sans` font from our Design System. Let's proceed to add this font to our project.

1. **Generate an assets folder**: Right-click on your project's root directory and select `New -> Directory`. Name this new folder `assets`.

2. **Inside the assets folder, create a fonts folder**: Right-click on the `assets` folder you've just created and select `New -> Directory`. Label this new folder `fonts`.

3. **Include your font files**: Move your `Nunito Sans` font files (usually with `.ttf` or `.otf` extensions) into the `fonts` folder. You can do this by dragging and dropping the files into the Android Studio window.

4. **Revise your pubspec.yaml**: Open the `pubspec.yaml` file and include the path to your font files under the `assets` section. Your `pubspec.yaml` should look somewhat like this:

```yaml
flutter:
  assets:
    - assets/fonts/
```

Remember to save the changes to your `pubspec.yaml` file and run the `flutter pub get` command in the terminal to update your project's dependencies after each modification.

You now have a custom font at your disposal for use in your Flutter application! In the following step, we'll employ this font in our text styles within the `XelaTextStyle` class.

**Step 7: Defining a Static fontFamily Constant**

One of the best practices when managing font styles is to create a static constant for the font family. This enables you to change the font throughout the entire application without having to adjust every individual style.

Incorporate the following code into the `XelaTextStyle` class:

```dart
import 'package:flutter/material.dart';

class XelaTextStyle {
  XelaTextStyle._();  

  // Font family
  static const String fontFamily = "Nunito Sans";

  // Font styles will be defined here
}
```

Now, we've created a static `fontFamily` constant that contains the name of our font. In the subsequent steps, we'll use this font name when we define our font styles. Should you decide to alter the font of your application later on, you'll only need to update this single value, and the changes will be propagated across all font styles that utilize `fontFamily`.

**Step 8: Understanding Font Styles in the Xela Design System in Figma**

Before we start translating our font styles into Flutter, let's first understand what styles are available in the Xela Design System in Figma. This will help us determine which styles we need to create in our Flutter project.

![Xela Design System: Typography Component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2aebib0hxxrljp0pesvz.png)

Here are the styles we have at our disposal:

- **Title1, Title2, Title3**: These styles are typically employed for various levels of headings in your app.

- **Headline**: This style is often designated for leading headlines or standout elements on the screen.

- **Subheadline**: This style is used for secondary headings or supplementary text under main titles.

- **Body, Body Bold, Body Small, Body Small Bold**: These styles are utilized for the primary text in your app. They include normal weight variations, bold, and a reduced font size option.

- **Caption**: This style is typically designated for captions under images or smaller text notes.

- **Button Large, Button Medium, Button Small**: These styles are intended for text on different sizes of buttons.

With an understanding of these styles, let's proceed to the next step where we'll start defining these styles in our Flutter project.

**Step 9: Defining the Title1 Style**

It's time to start applying font styles from our Design System to our Flutter project. We'll kick things off with `Title1`.

Incorporate the following code into the `XelaTextStyle` class:

```dart
import 'package:flutter/material.dart';

class XelaTextStyle {
  XelaTextStyle._();  

  // Font family
  static const String fontFamily = "Nunito Sans";

  // Font styles
  static const TextStyle Title1 = TextStyle(
    fontSize: 60,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );
  
  // Other styles will be defined here
}
```

We've now defined the `Title1` style, which can be applied throughout our app. This style sets the font size to 60, the weight to 800 (corresponding to extra bold in Flutter), and uses our custom "Nunito Sans" font.

In the subsequent steps, we'll continue defining the remaining styles from our Design System.

**Step 10: Incorporating the Remaining Styles**

Let's proceed with adding the rest of the font styles to our `XelaTextStyle` class. 

The updated `XelaTextStyle` class should look as follows:

```dart
import 'package:flutter/material.dart';

class XelaTextStyle {
  XelaTextStyle._();  

  // Font family
  static const String fontFamily = "Nunito Sans";

  // Font styles
  static const TextStyle Title1 = TextStyle(
    fontSize: 60,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle Title2 = TextStyle(
    fontSize: 48,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle Title3 = TextStyle(
    fontSize: 34,
    fontWeight: FontWeight.w900,
    fontFamily: fontFamily,
  );

  static const TextStyle Headline = TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle Subheadline = TextStyle(
    fontSize: 18,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle Body = TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.normal,
    fontFamily: fontFamily,
  );

  static const TextStyle BodyBold = TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle SmallBody = TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.normal,
    fontFamily: fontFamily,
  );

  static const TextStyle SmallBodyBold = TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle Caption = TextStyle(
    fontSize: 12,
    fontWeight: FontWeight.w700,
    fontFamily: fontFamily,
  );

  static const TextStyle ButtonLarge = TextStyle(
    fontSize: 16,
    fontWeight: FontWeight.w700,
    fontFamily: fontFamily,
  );

  static const TextStyle ButtonMedium = TextStyle(
    fontSize: 14,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );

  static const TextStyle ButtonSmall = TextStyle(
    fontSize: 12,
    fontWeight: FontWeight.w800,
    fontFamily: fontFamily,
  );
}
```

The `XelaTextStyle` class now includes all the font styles based on your Design System. You can employ these styles throughout your app by referencing them as `XelaTextStyle.Title1`, `XelaTextStyle.Body`, etc.

Please keep in mind that the font weight in Flutter might not precisely match what you see in your Design System, depending on the font you're employing. This is due to the differing interpretation of font weights between Flutter and some design systems. If the font doesn't appear as expected, you might need to adjust the font weight to achieve the desired appearance.

**Step 11: Demonstrating Font Style Usage**

Now that we've established our font styles, let's illustrate how they can be utilized in a Flutter application.

1. **Implementing Styles in a Text Widget**

The `Text` widget in Flutter accepts a `style` argument, which lets you set the text style. We can directly pass our styles from `XelaTextStyle` into this argument.

```dart
Text(
  'Hello, Flutter!',
  style: XelaTextStyle.Headline,
)
```

2. **Applying Styles to Buttons**

We can also implement our text styles in other widgets, such as buttons.

```dart
ElevatedButton(
  onPressed: () {},
  child: Text(
    'Press me',
    style: XelaTextStyle.ButtonLarge,
  ),
)
```

3. **Utilizing Styles in AppBar**

The AppBar in Flutter also permits you to customize the text style for its title.

```dart
AppBar(
  title: Text(
    'Hello, Flutter!',
    style: XelaTextStyle.Title1,
  ),
)
```

4. **Using Styles in ListTile**

`ListTile` allows you to set text styles for its leading and title text.

```dart
ListTile(
  leading: Text(
    'Leading Text',
    style: XelaTextStyle.Subheadline,
  ),
  title: Text(
    'Title Text',
    style: XelaTextStyle.Body,
  ),
)
```

As you can see, our font styles can be employed in diverse contexts within our app, fostering consistency and simplifying the management of text styles.

**Conclusion**

Incorporating font styles effectively in your Flutter project is of paramount importance. It not only ensures visual consistency throughout your app but also enhances the user experience. Moreover, centralizing font styles in a dedicated class, as we've done with `XelaTextStyle`, streamlines their management and makes it easier to apply changes uniformly.

We hope this step-by-step guide has provided valuable insights into how to create and utilize font styles in a Flutter project, drawing from our experience in developing the Xela Design System. By following these practices, you can elevate the appeal and professionalism of your Flutter applications.

To further simplify your Flutter UI development, we invite you to explore our website at [xelaui.com](https://xelaui.com). There, you'll discover our comprehensive Flutter library, replete with numerous pre-built components for your projects. And as a token of appreciation for our readers, we offer a **25% discount** with the promo code **4EOJFLM**.

For a hands-on experience, you can check out [our library's demo](https://xelaui.com/docs-flutter/demo.html) in an existing project. This demo also showcases a section dedicated to font styles, similar to what we've discussed in this article.

Thank you for taking the time to read this article. We hope it will assist you in creating captivating and professional Flutter applications.