使用自定义字体

尽管 Android 和 iOS 已经提供了一套高质量系统字体,但设计师还是希望能支持自定义字体。你可能需要使用设计师提供的定制字体,或者从 Google Fonts 下载的字体。

字体是指构成特定字体风格的字形或形状的集合。也是在特定字重或变化下的一种表现形式。 Roboto 是一种字体,Roboto Bold 也是一种字体。

Flutter 可以很方便地使用自定义字体,不仅能够将其用于整个应用里,还可以用在某个单独的 widget 中。本指南参照下面的步骤使用自定义字体:

  1. 选择你的字体。

  2. 导入字体文件。

  3. pubspec.yaml 中声明字体。

  4. 设置默认字体。

  5. 将字体用于特定 widget。

你不需要按照每个步骤进行操作。指南最后提供了已完成的示例文件。

字体的选择

#

字体的选择不应仅仅是一种偏好。请考虑哪些文件格式可与 Flutter 配合使用,以及字体会如何影响设计和应用的性能。

选择已支持的字体格式

#

Flutter 支持以下的字体格式:

  • OpenType 字体集:.ttc

  • TrueType 字体:.ttf

  • OpenType 字体:.otf

Flutter 在桌面平台上不支持 Web Open 字体格式(.woff.woff2)的字体。

Choose fonts for their specific benefits

#

Few sources agree on what a font file type is or which uses less space. The key difference between font file types involves how the format encodes the glyphs in the file. Most TrueType and OpenType font files have similar capabilities as they borrowed from each other as the formats and fonts improved over time.

Which font you should use depends on the following considerations.

  • How much variation you need for fonts in your app?
  • How much file size you can accept fonts using in your app?
  • How many languages you need to support in your app?

Research what options a given font offers, like more than one weight or style per font file, variable font capability, the availability of multiple font files for a multiple font weights, or more than one width per font.

Choose the typeface or font family that meets the design needs of your app.

Import the font files

#

To work with a font, import its font files into your Flutter project.

To import font files, perform the following steps.

  1. If necessary, to match the remaining steps in this guide, change the name of your Flutter app to custom_fonts.

    mv /path/to/my_app /path/to/custom_fonts
  2. Navigate to the root of your Flutter project.

    cd /path/to/custom_fonts
  3. Create a fonts directory at the root of your Flutter project.

    mkdir fonts
  4. Move or copy the font files in a fonts or assets folder at the root of your Flutter project.

    cp ~/Downloads/*.ttf ./fonts

The resulting folder structure should resemble the following:

custom_fonts/
|- fonts/
  |- Raleway-Regular.ttf
  |- Raleway-Italic.ttf
  |- RobotoMono-Regular.ttf
  |- RobotoMono-Bold.ttf

Declare the font in the pubspec.yaml file

#

After you've downloaded a font, include a font definition in the pubspec.yaml file. This font definition also specifies which font file should be used to render a given weight or style in your app.

Define fonts in the pubspec.yaml file

#

To add font files to your Flutter app, complete the following steps.

  1. Open the pubspec.yaml file at the root of your Flutter project.

    vi pubspec.yaml
  2. Paste the following YAML block after the flutter declaration.

    yaml
      fonts:
        - family: Raleway
          fonts:
            - asset: fonts/Raleway-Regular.ttf
            - asset: fonts/Raleway-Italic.ttf
              style: italic
        - family: RobotoMono
          fonts:
            - asset: fonts/RobotoMono-Regular.ttf
            - asset: fonts/RobotoMono-Bold.ttf
              weight: 700

This pubspec.yaml file defines the italic style for the Raleway font family as the Raleway-Italic.ttf font file. When you set style: TextStyle(fontStyle: FontStyle.italic), Flutter swaps Raleway-Regular with Raleway-Italic.

The family value sets the name of the typeface. You use this name in the fontFamily property of a TextStyle object.

The value of an asset is a relative path from the pubspec.yaml file to the font file. These files contain the outlines for the glyphs in the font. When building the app, Flutter includes these files in the app's asset bundle.

Include font files for each font

#

Different typefaces implement font files in different ways. If you need a typeface with a variety of font weights and styles, choose and import font files that represent that variety.

When you import a font file that doesn't include either multiple fonts within it or variable font capabilities, don't use the style or weight property to adjust how they display. If you do use those properties on a regular font file, Flutter attempts to simulate the look. The visual result will look quite different from using the correct font file.

Set styles and weights with font files

#

When you declare which font files represent styles or weights of a font, you can apply the style or weight properties.

Set font weight

#

The weight property specifies the weight of the outlines in the file as an integer multiple of 100, between 100 and 900. These values correspond to the FontWeight and can be used in the fontWeight property of a TextStyle object.

In the pubspec.yaml shown in this guide, you defined RobotoMono-Bold as the 700 weight of the font family. To use the RobotoMono-Bold font that you added to your app, set fontWeight to FontWeight.w700 in your TextStyle widget.

If you hadn't added RobotoMono-Bold to your app, Flutter attempts to make the font look bold. The text then might appear to be somewhat darker.

You can't use the weight property to override the weight of the font. You can't set RobotoMono-Bold to any other weight than 700. If you set TextStyle(fontFamily: 'RobotoMono', fontWeight: FontWeight.w900), the displayed font would still render as however bold RobotoMono-Bold looks.

Set font style

#

The style property specifies whether the glyphs in the font file display as either italic or normal. These values correspond to the FontStyle. You can use these styles in the fontStyle property of a TextStyle object.

In the pubspec.yaml shown in this guide, you defined Raleway-Italic as being in the italic style. To use the Raleway-Italic font that you added to your app, set style: TextStyle(fontStyle: FontStyle.italic). Flutter swaps Raleway-Regular with Raleway-Italic when rendering.

If hadn't added Raleway-Italic to your app, Flutter attempts to make the font look italic. The text then might appear to be leaning to the right.

You can't use the style property to override the glyphs of a font. If you set TextStyle(fontFamily: 'Raleway', fontStyle: FontStyle.normal), the displayed font would still render as italic. The regular style of an italic font is italic.

Set a font as the default

#

To apply a font to text, you can set the font as the app's default font in its theme.

To set a default font, set the fontFamily property in the app's theme. Match the fontFamily value to the family name declared in the pubspec.yaml file.

The result would resemble the following code.

dart
return MaterialApp(
  title: 'Custom Fonts',
  // Set Raleway as the default app font.
  theme: ThemeData(fontFamily: 'Raleway'),
  home: const MyHomePage(),
);

To learn more about themes, check out the Using Themes to share colors and font styles recipe.

Set the font in a specific widget

#

To apply the font to a specific widget like a Text widget, provide a TextStyle to the widget.

For this guide, try to apply the RobotoMono font to a single Text widget. Match the fontFamily value to the family name declared in the pubspec.yaml file.

The result would resemble the following code.

dart
child: Text(
  'Roboto Mono sample',
  style: TextStyle(fontFamily: 'RobotoMono'),
),

Try the complete example

#

Download fonts

#

Download the Raleway and RobotoMono font files from Google Fonts.

Update the pubspec.yaml file

#
  1. Open the pubspec.yaml file at the root of your Flutter project.

    vi pubspec.yaml
  2. Replace its contents with the following YAML.

    yaml
    name: custom_fonts
    description: An example of how to use custom fonts with Flutter
    
    dependencies:
      flutter:
        sdk: flutter
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
    
    flutter:
      fonts:
        - family: Raleway
          fonts:
            - asset: fonts/Raleway-Regular.ttf
            - asset: fonts/Raleway-Italic.ttf
              style: italic
        - family: RobotoMono
          fonts:
            - asset: fonts/RobotoMono-Regular.ttf
            - asset: fonts/RobotoMono-Bold.ttf
              weight: 700
      uses-material-design: true

Use this main.dart file

#
  1. Open the main.dart file in the lib/ directory of your Flutter project.

    vi lib/main.dart
  2. Replace its contents with the following Dart code.

    dart
    import 'package:flutter/material.dart';
    
    void main() => runApp(const MyApp());
    
    class MyApp extends StatelessWidget {
      const MyApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Custom Fonts',
          // Set Raleway as the default app font.
          theme: ThemeData(fontFamily: 'Raleway'),
          home: const MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatelessWidget {
      const MyHomePage({super.key});
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // The AppBar uses the app-default Raleway font.
          appBar: AppBar(title: const Text('Custom Fonts')),
          body: const Center(
            // This Text widget uses the RobotoMono font.
            child: Text(
              'Roboto Mono sample',
              style: TextStyle(fontFamily: 'RobotoMono'),
            ),
          ),
        );
      }
    }

The resulting Flutter app should display the following screen.