使用自定义字体

尽管 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

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 属性上使用。

    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.

  • style 属性指定文件中字体的轮廓是否为 italicnormal。这些值对应 FontStyle 并能够在 TextStyle 对象的 fontStyle 属性上使用。

    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.

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: 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 is 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(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Custom Fonts',
      // Set Raleway as the default app font.
      theme: ThemeData(fontFamily: 'Raleway'),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // The AppBar uses the app-default Raleway font.
      appBar: AppBar(title: Text('Custom Fonts')),
      body: Center(
        // This Text widget uses the RobotoMono font.
        child: Text(
          'Roboto Mono sample',
          style: TextStyle(fontFamily: 'RobotoMono'),
        ),
      ),
    );
  }
}

Custom Fonts Demo