Flutter动态加载设置字体
Flutter 有好多关于设置字体样式的教程,官网上就有,但好多都是把字体放到 assets 资源包,指定加载,这样会让 App 的包超级大不说,字体加载还死板。今天介绍一种动态加载字体的教程。
其实也超级简单,核心代码就几句:
// 构建 loader
var 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 数据也可以从网上下载获取,实现网上下载替换字体
Future
fetchFontByteData() => 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 initState
super.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 数据也可以从网上下载获取,实现网上下载替换字体
Future
fetchFontByteData() => rootBundle.load('assets/行楷.ttf');}
评论