Flutter字体加载插件web_fonts的使用

发布于 1周前 作者 htzhanglong 来自 Flutter

Flutter字体加载插件web_fonts的使用

简介

web_fonts 是一个用于在Flutter应用中懒加载Web字体的插件。通过这个插件,你可以轻松地从网络加载并使用Google Fonts等提供的字体,而无需将字体文件打包到应用中。这不仅可以减少应用的体积,还可以动态加载不同风格和权重的字体。

开始使用

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 web_fonts 依赖:

dependencies:
  flutter:
    sdk: flutter
  web_fonts: ^最新版本

然后运行 flutter pub get 来安装依赖。

2. 定义字体

接下来,你需要定义你想要使用的字体。以下是一个示例,展示了如何注册和使用 NotoSansKR 字体的不同变体(如常规、粗体等)。

import 'package:flutter/material.dart';
import 'package:web_fonts/fonts/web_fonts_descriptor.dart';
import 'package:web_fonts/fonts/web_fonts_variant.dart';
import 'package:web_fonts/web_fonts.dart';

class NotoSansKRFont {
  static const _fontFamily = 'NotoSansKR';
  static bool _registered = false;

  // 注册字体文件
  static register() {
    if (_registered) {
      return;
    }

    WebFonts.register(_fontFamily, {
      WebFontsVariant(
        fontWeight: FontWeight.w300,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOelzI7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w400,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/PbykFmXiEBPT4ITbgNA5Cgm20HTs4JMMuA.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w500,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOIl3I7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w700,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOalvI7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w900,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOUlnI7rgQsWYrzw.otf',
      ),
    });

    _registered = true;
  }

  // 获取 TextStyle
  static TextStyle getTextStyle([TextStyle textStyle]) {
    register();

    return WebFonts.getTextStyle(_fontFamily, textStyle: textStyle);
  }

  // 获取 TextTheme
  static TextTheme getTextTheme([TextTheme textTheme]) {
    register();

    return WebFonts.getTextTheme(_fontFamily, textTheme);
  }
}
3. 使用字体

在你的应用中使用这些字体非常简单。你可以通过 NotoSansKRFont.getTextStyle() 方法来获取 TextStyle,并在 Text 小部件中使用它。

Text(
  '这是 NotoSansKR 字体',
  style: NotoSansKRFont.getTextStyle(),
),
4. 许可证

如果你在应用中使用了来自 Google Fonts 的字体,确保添加相应的许可证。例如,Lato 字体有一个名为 OFL.txt 的许可证文件。你需要将这些许可证添加到 Flutter 应用的 LicenseRegistry 中。

void main() {
  LicenseRegistry.addLicense(() async* {
    final license = await rootBundle.loadString('google_fonts/OFL.txt');
    yield LicenseEntryWithLineBreaks(['google_fonts'], license);
  });

  runApp(MyApp());
}

完整示例

以下是一个完整的示例,展示了如何在Flutter应用中使用 web_fonts 插件来加载和显示 NotoSansKR 字体。

import 'package:flutter/material.dart';
import 'package:web_fonts/fonts/web_fonts_descriptor.dart';
import 'package:web_fonts/fonts/web_fonts_variant.dart';
import 'package:web_fonts/web_fonts.dart';

// 定义 NotoSansKR 字体
class NotoSansKRFont {
  static const _fontFamily = 'NotoSansKR';
  static bool _registered = false;

  // 注册字体文件
  static register() {
    if (_registered) {
      return;
    }

    WebFonts.register(_fontFamily, {
      WebFontsVariant(
        fontWeight: FontWeight.w300,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOelzI7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w400,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/PbykFmXiEBPT4ITbgNA5Cgm20HTs4JMMuA.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w500,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOIl3I7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w700,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOalvI7rgQsWYrzw.otf',
      ),
      WebFontsVariant(
        fontWeight: FontWeight.w900,
        fontStyle: FontStyle.normal,
      ): WebFontsFile(
        'http://fonts.gstatic.com/s/notosanskr/v13/Pby7FmXiEBPT4ITbgNA5CgmOUlnI7rgQsWYrzw.otf',
      ),
    });

    _registered = true;
  }

  // 获取 TextStyle
  static TextStyle getTextStyle([TextStyle textStyle]) {
    register();

    return WebFonts.getTextStyle(_fontFamily, textStyle: textStyle);
  }

  // 获取 TextTheme
  static TextTheme getTextTheme([TextTheme textTheme]) {
    register();

    return WebFonts.getTextTheme(_fontFamily, textTheme);
  }
}

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

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final TextStyle display1 = Theme.of(context)
        .textTheme
        .bodyLarge!
        .copyWith(fontWeight: FontWeight.normal);

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Text(
              '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${display1.fontFamily})',
              style: display1,
            ),
            Divider(),
            Text(
              '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${display1.fontFamily}, Bold)',
              style: display1.copyWith(
                fontWeight: FontWeight.bold,
              ),
            ),
            Divider(),
            DefaultTextStyle(
              style: NotoSansKRFont.getTextStyle(display1),
              child: Builder(
                builder: (context) {
                  final defaultTextStyle = DefaultTextStyle.of(context).style;

                  return Column(
                    children: [
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily})',
                      ),
                      Divider(),
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Bold)',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                    ],
                  );
                },
              ),
            ),
            Divider(),
            DefaultTextStyle(
              style: NotoSansKRFont.getTextStyle(display1),
              child: Builder(
                builder: (context) {
                  final defaultTextStyle = DefaultTextStyle.of(context).style;

                  return Column(
                    children: [
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Thin)',
                        style: TextStyle(
                          fontWeight: FontWeight.w300,
                        ),
                      ),
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Regular)',
                      ),
                      Divider(),
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Medium)',
                        style: TextStyle(
                          fontWeight: FontWeight.w500,
                        ),
                      ),
                      Divider(),
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Bold)',
                        style: TextStyle(
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Divider(),
                      Text(
                        '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${defaultTextStyle.fontFamily}, Black)',
                        style: TextStyle(
                          fontWeight: FontWeight.w900,
                        ),
                      ),
                    ],
                  );
                },
              ),
            ),
            Divider(),
            Text(
              '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${NotoSansKRFont.getTextStyle(display1).fontFamily})',
              style: NotoSansKRFont.getTextStyle(display1),
            ),
            Divider(),
            Text(
              '"oO08 iIlL1 g9qCGQ ~-+=>"; 한국어 (${NotoSansKRFont.getTextStyle(display1).fontFamily}, Bold)',
              style: NotoSansKRFont.getTextStyle(display1.copyWith(
                fontWeight: FontWeight.bold,
              )),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter字体加载插件web_fonts的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter字体加载插件web_fonts的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中使用web_fonts插件来加载网络字体的详细代码示例。web_fonts插件允许你在Flutter的Web应用中加载和使用自定义的Web字体。

步骤1:添加依赖

首先,你需要在pubspec.yaml文件中添加web_fonts依赖:

dependencies:
  flutter:
    sdk: flutter
  web_fonts: ^2.1.1  # 请检查最新版本号

步骤2:安装依赖

在命令行中运行以下命令来安装依赖:

flutter pub get

步骤3:加载网络字体

在你的Flutter项目中,你可以通过WebFonts.load方法来加载网络字体。下面是一个完整的示例,展示了如何在Flutter Web应用中使用网络字体。

1. 创建一个Dart文件来定义字体

lib目录下创建一个新的Dart文件,比如fonts.dart,并在其中定义你要加载的字体:

// lib/fonts.dart
import 'package:web_fonts/web_fonts.dart';

Future<void> loadFonts() async {
  await WebFonts.load(
    google: [
      WebFont.google('Roboto', 'https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'),
    ],
    custom: [
      WebFont.custom('MyCustomFont', 'https://example.com/path/to/font.css'),
    ],
  );
}

在这个例子中,我们加载了一个Google字体(Roboto)和一个自定义网络字体(MyCustomFont)。

2. 在你的应用中加载字体

在你的主应用文件中(比如lib/main.dart),确保在应用启动时加载字体:

// lib/main.dart
import 'package:flutter/material.dart';
import 'fonts.dart';  // 导入你定义的字体文件

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await loadFonts();  // 加载字体
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Web Fonts Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Web Fonts Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'Hello, World!',
              style: TextStyle(
                fontFamily: 'Roboto',  // 使用加载的Google字体
                fontSize: 24,
                fontWeight: FontWeight.w700,
              ),
            ),
            SizedBox(height: 20),
            Text(
              'This is custom font text.',
              style: TextStyle(
                fontFamily: 'MyCustomFont',  // 使用加载的自定义字体
                fontSize: 24,
              ),
            ),
          ],
        ),
      ),
    );
  }
}

注意事项

  1. 网络字体文件:确保你提供的字体URL是有效的,并且字体文件可以被正确加载。
  2. 字体名称:在TextStyle中使用的fontFamily名称应该与你在WebFont.googleWebFont.custom中定义的名称一致。
  3. 异步加载:字体加载是异步的,因此在应用启动时调用await loadFonts()以确保字体在使用前已加载完毕。

通过上述步骤,你就可以在Flutter Web应用中使用web_fonts插件来加载和使用网络字体了。

回到顶部