Flutter动态字体加载插件dynamic_fonts的使用
Flutter动态字体加载插件dynamic_fonts的使用
简介
dynamic_fonts
是一个用于Flutter的包,它允许你相对轻松地将托管在任何地方的自定义字体添加到你的应用中。这与 google_fonts
包类似,但不仅限于Google Fonts提供的字体,而是可以为任意托管位置的字体。
dynamic_fonts
是 google_fonts
的一个分支,它暴露出更多的API,使你可以指定自己的字体。
为什么选择这个包?
如果你的应用提供了多种字体供用户选择,并且:
- 某些字体可能根据用户偏好完全不被使用;
- 将所有字体都打包到应用中会大大增加应用体积;
那么这个包提供了一种方便的方法来动态加载字体,并保持初始下载体积较小。
开始使用
通过 dynamic_fonts
包,.ttf
或 .otf
文件不需要存储在你的assets文件夹中并在pubspec中映射。相反,它们可以通过HTTP在运行时获取一次,并缓存在应用程序的文件系统中。这非常适合开发,也可以是希望减少应用包大小的生产应用的首选行为。当然,你仍然可以选择将字体文件包含在assets中,Dynamic Fonts
包会优先使用预打包的文件而不是通过HTTP获取。
注册字体
要注册字体,你需要提供字体家族名称和从 DynamicFontsVariant
到 DynamicFontsFile
的映射。下面以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
更多关于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. 配置动态字体
在应用的MaterialApp
或CupertinoApp
的顶层,你可以配置动态字体。通常,这会在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
参数是你将在TextStyle
的fontFamily
属性中使用的名称。DynamicFonts.load
是一个异步操作,因此你可能需要在加载完成后更新UI(例如通过setState
)。
这个示例展示了如何在Flutter应用中使用dynamic_fonts
插件来动态加载字体。你可以根据需要调整字体URL和其他配置参数。