使用自定义字体

尽管 Android 和 iOS 已经提供了一套高质量系统字体,然而通常设计师还是会要求使用自定义字体。例如,你可能需要使用设计师提供的自定义字体,或者从 Google Fonts 下载的字体。

Although Android and iOS offer high quality system fonts, one of the most common requests from designers is for custom fonts. For example, you might have a custom-built font from a designer, or perhaps you downloaded a font from Google Fonts.

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

Flutter works with custom fonts and you can apply a custom font across an entire app or to individual widgets. This recipe creates an app that uses custom fonts with the following steps:

步骤

Directions

  1. 导入字体文件

    Import the font files

  2. pubspec.yaml 中声明字体

    Declare the font in the pubspec.yaml

  3. 设置默认字体

    Set a font as the default

  4. 将字体用于特定 widget

    Use a font in a specific widget

1. 导入字体文件

1. Import the font files

要使用字体,你需要将字体文件导入到项目中。常见的做法是将字体文件放在项目根目录下的 fonts 或者 assets 文件夹中。

To work with a font, import the font files into the project. It’s common practice to put font files in a fonts or assets folder at the root of a Flutter project.

例如,如果你想要在项目中导入 Raleway 和 Roboto Mono 字体,文件夹结构会像下面这样:

For example, to import the Raleway and Roboto Mono font files into a project, the folder structure might look like this:

awesome_app/
  fonts/
    Raleway-Regular.ttf
    Raleway-Italic.ttf
    RobotoMono-Regular.ttf
    RobotoMono-Bold.ttf

已支持的字体格式

Supported font formats

Flutter 支持以下的字体格式:

Flutter supports the following font formats:

  • .ttf
  • .otf

Flutter 在所有平台上均尚未支持 .woff.woff2 字体。

Flutter does not support .woff and .woff2 fonts for all platforms.

2. 在 pubspec.yaml 中声明字体

2. Declare the font in the pubspec

现在你已经有一个字体可以使用,接下来则需要告诉 Flutter 它在哪。你可以在 pubspec.yaml 中像下面这样声明:

Once you’ve identified a font, tell Flutter where to find it. You can do this by including a font definition in the pubspec.yaml file.

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

pubspec.yaml 选项的定义

pubspec.yaml option definitions

family 属性决定了字体的名称,你将会在 TextStylefontFamily 属性中用到。

The family determines the name of the font, which you use in the fontFamily property of a TextStyle object.

asset 是字体文件对于 pubspec.yaml 文件的相对路径。这些文件包含了字体中字形的轮廓。构建应用时,这些文件将会被包含在应用程序的资源包中。

The asset is a path to the font file, relative to the pubspec.yaml file. These files contain the outlines for the glyphs in the font. When building the app, these files are included in the app’s asset bundle.

单个字体可以引用多个不同轮廓字重及风格的文件:

A single font can reference many different files with different outline weights and styles:

  • weight 属性指定了文件中字体轮廓的字重为 100 的整数倍,并且范围在 100 和 900 之间。这些值对应 FontWeight 并能够在 TextStyle 对象的 fontWeight 属性上使用。例如,如果你想使用上面定义的 RobotoMono-Bold 字体,你可以在 TextStyle 中将 fontWeight 设置为 FontWeight.w700

    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. For example, if you want to use the RobotoMono-Bold font defined above, you would set fontWeight to FontWeight.w700 in your TextStyle.

    需要注意的是,定义 weight 属性不会覆盖字体的实际粗细。你无法使用 FontWeight.w100 访问 RobotoMono-Bold,即使其 weight 设置为了 100。

    Note that defining the weight property does not override the actual weight of the font. You would not be able to access RobotoMono-Bold with FontWeight.w100, even if its weight was set to 100.

  • style 属性指定文件中字体的轮廓是否为 italicnormal。这些值对应 FontStyle 并能够在 TextStyle 对象的 fontStyle 属性上使用。例如,如果你想使用上面定义的 Raleway-Italic 字体,你可以在 TextStyle 中将 fontStyle 设置为 FontStyle.italic

    The style property specifies whether the outlines in the file are italic or normal. These values correspond to the FontStyle and can be used in the fontStyle property of a TextStyle object. For example, if you want to use the Raleway-Italic font defined above, you would set fontStyle to FontStyle.italic in your TextStyle.

    需要注意的是,定义 style 属性不会更改字体的实际样式;你无法使用 FontStyle.normal 访问 Raleway-Italic,即使其 style` 设置为了 normal。

    Note that defining the style property does not override the actual style of the font; You would not be able to access Raleway-Italic with FontStyle.normal, even if its style was set to normal.

3. 设置默认字体

3. Set a font as the default

关于如何应用这些字体,你有两种选择:将其设为默认字体,或者仅在某些特定 widget 中使用。

You have two options for how to apply fonts to text: as the default font or only within specific widgets.

如果你想要设为默认字体,请将 fontFamily 设为应用(全局)theme 的属性的一部分。提供的 fontFamily 的值必须与 pubspec.yaml 中声明的名称相匹配。

To use a font as the default, set the fontFamily property as part of the app’s theme. The value provided to fontFamily must match the family name declared in the pubspec.yaml.

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

有关主题的更多信息,请参阅文档: 使用 Themes 统一颜色和字体风格

For more information on themes, see the Using Themes to share colors and font styles recipe.

4. 将字体用于特定 Widget

4. Use the font in a specific widget

如果你希望在特定 Widget(例如 Text Widget)中使用该字体,可以通过 TextStyle 中进行指定。

If you want to apply the font to a specific widget, such as a Text widget, provide a TextStyle to the widget.

在这个例子中,我们将在一个 Text Widget 上使用 RobotoMono 字体。同样的,这里的 fontFamily 的值必须与 pubspec.yaml 中声明的值相匹配。

In this example, apply the RobotoMono font to a single Text widget. Once again, the fontFamily must match the family name declared in the pubspec.yaml.

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

字体样式

TextStyle

如若 TextStyle 指定的字体样式缺少相应的字体文件, Engine 则会使用一个更加通用的字体文件,并尝试推断所请求的字体 weight 和样式的轮廓。

If a TextStyle object specifies a weight or style for which there is no exact font file, the engine uses one of the more generic files for the font and attempts to extrapolate outlines for the requested weight and style.

完整样例

Complete example

字体

Fonts

Raleway 和 RobotoMono 字体是从 Google Fonts 下载的。

The Raleway and RobotoMono fonts were downloaded from Google Fonts.

pubspec.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

main.dart

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: 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({Key? key}) : super(key: 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'),
        ),
      ),
    );
  }
}

Custom Fonts Demo