Flutter动态字体加载插件dynamic_fonts的使用

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

Flutter动态字体加载插件dynamic_fonts的使用

简介

dynamic_fonts 是一个用于Flutter的包,它允许你相对轻松地将托管在任何地方的自定义字体添加到你的应用中。这与 google_fonts 包类似,但不仅限于Google Fonts提供的字体,而是可以为任意托管位置的字体。

dynamic_fontsgoogle_fonts 的一个分支,它暴露出更多的API,使你可以指定自己的字体。

为什么选择这个包?

如果你的应用提供了多种字体供用户选择,并且:

  1. 某些字体可能根据用户偏好完全不被使用;
  2. 将所有字体都打包到应用中会大大增加应用体积;

那么这个包提供了一种方便的方法来动态加载字体,并保持初始下载体积较小。

开始使用

通过 dynamic_fonts 包,.ttf.otf 文件不需要存储在你的assets文件夹中并在pubspec中映射。相反,它们可以通过HTTP在运行时获取一次,并缓存在应用程序的文件系统中。这非常适合开发,也可以是希望减少应用包大小的生产应用的首选行为。当然,你仍然可以选择将字体文件包含在assets中,Dynamic Fonts 包会优先使用预打包的文件而不是通过HTTP获取。

注册字体

要注册字体,你需要提供字体家族名称和从 DynamicFontsVariantDynamicFontsFile 的映射。下面以FiraGO字体为例展示如何实现:

class FiraGoFile extends DynamicFontsFile {
  FiraGoFile(this.variant, String expectedFileHash, int expectedLength)
      : super(expectedFileHash, expectedLength);

  final DynamicFontsVariant variant;

  String get _dir {
    switch (variant.fontStyle) {
      case FontStyle.normal:
        return 'Roman';
      case FontStyle.italic:
        return 'Italic';
    }
    throw Exception('Unknown style: ${variant.fontStyle}');
  }

  @override
  String get url =>
      'https://raw.githubusercontent.com/bBoxType/FiraGO/9882ba0851f88ab904dc237f250db1d45641f45d/Fonts/FiraGO_TTF_1001/$_dir/FiraGO-${variant.toApiFilenamePart()}.ttf';
}

void _initCustomFonts() {
  DynamicFonts.register(
    'FiraGO',
    [
      _FiraGoFile(
        const DynamicFontsVariant(
          fontWeight: FontWeight.w400,
          fontStyle: FontStyle.normal,
        ),
        '495901c0c608ea265f4c31aa2a4c7a313e5cc2a3dd610da78a447fe8e07454a2',
        804888,
      ),
      _FiraGoFile(
        const DynamicFontsVariant(
          fontWeight: FontWeight.w400,
          fontStyle: FontStyle.italic,
        ),
        '36713ecac376845daa58738d2c2ba797cf6f6477b8c5bb4fa79721dc970e8081',
        813116,
      ),
    ].fold<Map<DynamicFontsVariant, DynamicFontsFile>>(
      {},
      (acc, file) => acc..[file.variant] = file,
    ),
  );
}

使用字体

使用 DynamicFonts.getFont 方法可以在文本样式中指定字体:

Text(
  'This is Dynamic Fonts',
  style: DynamicFonts.getFont(
    'FiraGO', 
    textStyle: TextStyle(color: Colors.blue, letterSpacing: .5),
  ),
),

// 或者在 TextTheme 中设置默认字体
MaterialApp(
  theme: ThemeData(
    textTheme: DynamicFonts.getTextTheme(
      'FiraGO',
      Theme.of(context).textTheme,
    ),
  ),
);

示例代码

以下是一个完整的示例代码,展示了如何在Flutter应用中使用 dynamic_fonts 包:

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

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

class MyApp extends StatelessWidget {
  @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({Key? key, required this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  @override
  void initState() {
    _initCustomFonts();
    super.initState();
  }

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    final TextStyle headlineMedium =
        Theme.of(context).textTheme.headlineMedium!;
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
              style: DynamicFonts.getFont('FiraGO', textStyle: headlineMedium),
            ),
            Text(
              '$_counter',
              style: DynamicFonts.getFont('FiraGO', fontStyle: FontStyle.italic),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

void _initCustomFonts() {
  DynamicFonts.register(
    'FiraGO',
    [
      _FiraGoFile(
        const DynamicFontsVariant(
          fontWeight: FontWeight.w400,
          fontStyle: FontStyle.normal,
        ),
        '495901c0c608ea265f4c31aa2a4c7a313e5cc2a3dd610da78a447fe8e07454a2',
        804888,
      ),
      _FiraGoFile(
        const DynamicFontsVariant(
          fontWeight: FontWeight.w400,
          fontStyle: FontStyle.italic,
        ),
        '36713ecac376845daa58738d2c2ba797cf6f6477b8c5bb4fa79721dc970e8081',
        813116,
      ),
    ].fold<Map<DynamicFontsVariant, DynamicFontsFile>>(
      {},
      (acc, file) => acc..[file.variant] = file,
    ),
  );
}

class _FiraGoFile extends DynamicFontsFile {
  _FiraGoFile(this.variant, String expectedFileHash, int expectedLength)
      : super(expectedFileHash, expectedLength);

  final DynamicFontsVariant variant;

  String get _dir {
    switch (variant.fontStyle) {
      case FontStyle.normal:
        return 'Roman';
      case FontStyle.italic:
        return 'Italic';
    }
    throw Exception('Unknown style: ${variant.fontStyle}');
  }

  @override
  String get url =>
      'https://raw.githubusercontent.com/bBoxType/FiraGO/9882ba0851f88ab904dc237f250db1d45641f45d/Fonts/FiraGO_TTF_1001/$_dir/FiraGO-${variant.toApiFilenamePart()}.ttf';
}

这段代码演示了如何在Flutter应用中集成并使用 dynamic_fonts 包来动态加载和显示自定义字体。


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

1 回复

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


当然,下面是一个关于如何在Flutter应用中使用dynamic_fonts插件来动态加载字体的代码示例。这个插件允许你在运行时加载字体,而无需在应用编译时将它们包含在项目中。

首先,确保你已经在pubspec.yaml文件中添加了dynamic_fonts依赖:

dependencies:
  flutter:
    sdk: flutter
  dynamic_fonts: ^x.y.z  # 替换为最新版本号

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

接下来,让我们编写一些Flutter代码来演示如何使用dynamic_fonts插件。

1. 导入必要的包

在你的Dart文件中(例如main.dart),首先导入dynamic_fonts包:

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

2. 配置动态字体

在应用的MaterialAppCupertinoApp的顶层,你可以配置动态字体。通常,这会在MyApp类的build方法中进行:

void main() {
  runApp(MyApp());
}

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

class DynamicFontsDemo extends StatefulWidget {
  @override
  _DynamicFontsDemoState createState() => _DynamicFontsDemoState();
}

class _DynamicFontsDemoState extends State<DynamicFontsDemo> {
  @override
  void initState() {
    super.initState();
    // 加载动态字体
    loadDynamicFont();
  }

  void loadDynamicFont() async {
    try {
      // 指定字体文件的URL(这里可以是网络URL或本地文件路径)
      String fontUrl = "https://example.com/path/to/your/font.ttf";
      
      // 加载字体
      await DynamicFonts.load(
        config: FontLoadingConfig(
          name: 'MyDynamicFont',
          url: fontUrl,
          weight: FontWeight.w400,
          style: FontStyle.normal,
        ),
      );

      // 更新UI(如果需要的话)
      setState(() {});
    } catch (e) {
      // 处理加载错误
      print("Failed to load font: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Dynamic Fonts Demo'),
      ),
      body: Center(
        child: Text(
          'Hello, Dynamic Fonts!',
          style: TextStyle(
            fontFamily: 'MyDynamicFont',  // 使用加载的字体
            fontSize: 24,
          ),
        ),
      ),
    );
  }
}

3. 注意事项

  • 确保你提供的字体URL是有效的,并且字体文件可以被访问。
  • FontLoadingConfig中的name参数是你将在TextStylefontFamily属性中使用的名称。
  • DynamicFonts.load是一个异步操作,因此你可能需要在加载完成后更新UI(例如通过setState)。

这个示例展示了如何在Flutter应用中使用dynamic_fonts插件来动态加载字体。你可以根据需要调整字体URL和其他配置参数。

回到顶部