Flutter动态加载设置字体
Flutter 有好多关于设置字体样式的教程,官网上就有,但好多都是把字体放到 assets 资源包,指定加载,这样会让 App 的包超级大不说,字体加载还死板。今天介绍一种动态加载字体的教程。
其实也超级简单,核心代码就几句:
// 构建 loadervar fontLoader = FontLoader('family');// 获取字体 (Future) 装载到 loader fontLoader.addFont(fetchFontByteData());// 加载字体await fontLoader.load();
下面稍微介绍一下其用法:
代码目录结构

模拟从手机应用中获取到文件字体并加载
思路: 用文件选择器找到字体文件路径,生成 file 并转为 ByteData,进行加载。就这么简单。核心代码如下:
void _loadFontFile() async {//字体路径String FontPath ="/Users/huangsir/Documents/Flutter/flutter_font_app/assets/繁体中文.ttf";var fontLoader = FontLoader("testFamily1"); //此处设置的名字需和使用时指定的family一致//获取本地字体File fontFile = File(FontPath);Uint8List bytes = fontFile.readAsBytesSync();fontLoader.loadFont(bytes, "testFamily1");await fontLoader.load().catchError((e) {print("loadFontFile erro: $e");});print("加载成功");_fontFamily = "testFamily1";setState(() {});}
获取 Asset 字体文件
//获取Asset字体文件void _loadFontFile1() async {var fontLoader = FontLoader('testFamily2');fontLoader.addFont(fetchFontByteData());await fontLoader.load().catchError((e) {print("loadFontFile erro: $e");});_fontFamily = "testFamily2";setState(() {});}//此处的byte 数据也可以从网上下载获取,实现网上下载替换字体FuturefetchFontByteData() => rootBundle.load('assets/行楷.ttf');
fetchFontByteData()就是获取 Future
应用
TextStyle 里面有一个 fontFamily 属性,可以用_fontFamily 字段接收,设置 TextStyle 即可。
Text('如果这世界复杂,虚假,喧哗',style: TextStyle(fontSize: 16,fontFamily: _fontFamily,color: Theme.of(context).primaryColor),)
效果

现实应用
现实 App 中替换字体大部分都是全局,即整个 App 的字体都会替换。这种实现思路就是用 Redux 或者其他状态管理替换 MaterialApp 中 ThemeData 的 fontFamily 属性,即可实现整个 App 字体切换。
MaterialApp(...theme: ThemeData(fontFamily: _fontFamily,),home: HomePage(),)
全部代码
import 'dart:io';import 'dart:typed_data';import 'package:flutter/material.dart';import 'package:flutter/services.dart';void main() {runApp(MyApp());}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return MaterialApp(title: '字体动态加载',theme: ThemeData(primarySwatch: Colors.blue,visualDensity: VisualDensity.adaptivePlatformDensity,),home: MyHomePage(title: '字体加载'),);}}class MyHomePage extends StatefulWidget {MyHomePage({Key key, this.title}) : super(key: key);final String title;_MyHomePageState createState() => _MyHomePageState();}class _MyHomePageState extends State<MyHomePage> {//接收设置字体样式String _fontFamily;void initState() {// TODO: implement initStatesuper.initState();}Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text(widget.title),),body: Center(child: Column(mainAxisAlignment: MainAxisAlignment.center,children:[ Text('如果这世界复杂,虚假,喧哗',style: TextStyle(fontSize: 16,fontFamily: _fontFamily,color: Theme.of(context).primaryColor),),RaisedButton(onPressed: () {//模拟加载字体文件_loadFontFile();},child: Text("模拟获取本地字体文件"),),RaisedButton(onPressed: () {//模拟加载字体文件_loadFontFile1();},child: Text("获取Assets字体文件"),)],),), //);}//现实运用中肯定是从手机中读取到字体文件导入,此处模拟获取本地字体文件,void _loadFontFile() async {//字体路劲String FontPath ="/Users/huangsir/Documents/Flutter/flutter_font_app/assets/繁体中文.ttf";var fontLoader = FontLoader("testFamily1"); //此处设置的名字需和使用时指定的family一致//获取本地字体File fontFile = File(FontPath);Uint8List bytes = fontFile.readAsBytesSync();fontLoader.loadFont(bytes, "testFamily1");await fontLoader.load().catchError((e) {print("loadFontFile erro: $e");});print("加载成功");_fontFamily = "testFamily1";setState(() {});}//获取Asset字体文件void _loadFontFile1() async {var fontLoader = FontLoader('testFamily2');fontLoader.addFont(fetchFontByteData());await fontLoader.load().catchError((e) {print("loadFontFile erro: $e");});_fontFamily = "testFamily2";setState(() {});}//此处的byte 数据也可以从网上下载获取,实现网上下载替换字体FuturefetchFontByteData() => rootBundle.load('assets/行楷.ttf');}
评论
