问题表现
- 安卓下的表现
- iphone下的表现
- 再看下实现的代码
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
appBar: AppBar(
title: const Text('Flutter 爬坑示例'),
),
body: const Center(
child: DefaultTextStyle(
style: TextStyle(
color: Colors.black,
fontSize: 16.0,
height: 2,
),
child: Column(
children: [
Text(
'AaBbCcDd 我是中文 123456 -- w100',
style: TextStyle(fontWeight: FontWeight.w100),
),
Text(
'AaBbCcDd 我是中文 123456 -- w200',
style: TextStyle(fontWeight: FontWeight.w200),
),
Text(
'AaBbCcDd 我是中文 123456 -- w300',
style: TextStyle(fontWeight: FontWeight.w300),
),
Text(
'AaBbCcDd 我是中文 123456 -- w400',
style: TextStyle(fontWeight: FontWeight.w400),
),
Text(
'AaBbCcDd 我是中文 123456 -- w500',
style: TextStyle(fontWeight: FontWeight.w500),
),
Text(
'AaBbCcDd 我是中文 123456 -- w600',
style: TextStyle(fontWeight: FontWeight.w600),
),
Text(
'AaBbCcDd 我是中文 123456 -- w700',
style: TextStyle(fontWeight: FontWeight.w700),
),
Text(
'AaBbCcDd 我是中文 123456 -- w800',
style: TextStyle(fontWeight: FontWeight.w800),
),
Text(
'AaBbCcDd 我是中文 123456 -- w900',
style: TextStyle(fontWeight: FontWeight.w900),
),
],
),
),
),
),
);
}
}
以上的例子中,我对每个Text
都设置了不同的fontWeight
,但是表现却完全不是想要的结果:
- 在安卓手机上,英文和数字是符合预期的,但是中文就不符合,要
w600
及以上才能产生效果,w600
以下基本没有任何加粗效果,约等于w100
- 在iphone上,英文和数字也是符合预期的,但是中文也是不符合,情况跟安卓还不一样,虽然也是要
w600
及以上才能起效果,但是w100-w500
完全是一样的,而且跟normal
一样,也就是约等于w400
于是上网搜索了一番,google,掘金等等,结果找到一个说法(github.com/CarGuo/gsy_… ),大致意思就是:
- 手机会根据配置的字体,如果没有配置,就用手机默认字体来渲染,但是由于手机对于中文的支持有限,或者对于
fontWeight
权重的支持有限,导致有些字体渲染不一致,例如中文,韩国文字等等 - 提供的解决方式就是通过配置
fontFamilyFallback
,于是我修改代码如下
// 主要修改公共样式部分
TextStyle(
color: Colors.black,
fontSize: 16.0,
height: 2,
fontFamilyFallback: [
"PingFang SC",
"Heiti SC",
"Roboto",
],
),
在 Flutter 中,fontFamilyFallback
是用于指定字体回退列表的属性,其主要作用是在指定的主要字体无法找到或加载失败时,依次尝试使用回退列表中的字体,以确保文本能够以合适的字体显示。
修改完后,我很高兴,以为应该可以爬出坑了,但是高兴了一半。查看结果发现,iphone没有问题,但是安卓还是没有效果。如下图
- iphone效果图,中文显示如预期
- 再看看安卓的,中文显示还是和原来一样
又经过了一顿google,掘金等等查找,来自多方面的总结,
- 除了以上的分析,虽然添加了
fontFamilyFallback
,但是对于PingFang SC
,Heiti SC
,Roboto
, 前面两个安卓系统不支持 - 而
Roboto
虽然安卓支持,但是对于fontWeight
支持度不够
于是网上有找到方案,就是引入自定义字体,但是该用什么字体呢?有的说用NotoSans
,Noto Sans 是谷歌(Google)与 Adobe 合作推出的一款无衬线字体。
但是经过我一番捣腾之后,发现NotoSans
其实也是对于中文支持不够,效果还是没有符合预期
最后我在某个网站发现,其实还有另外一种字体NotoSansSC
Noto Sans SC 是 Noto 字体系列中的一个分支,专门用于显示简体中文文字。“SC”是 “Simplified Chinese”的缩写,意指简化字。这款字体是为了确保在显示任何简体中文文本时,即使某些非常见或特殊的字符不在常见的字体支持范围内,也能够正确地显示出来。
于是我就开始测试该方法
- 先下载
NotoSansSC
,到谷歌网站 (fonts.google.com/noto/specim… - 在flutter项目根目录创建个目录存放,一般是根目录下
assets/fonts/
- 然后找到根目录下的
pubspec.yaml
,添加一下代码
fonts:
- family: NotoSansSC // 这个名字可以自己定义
fonts:
- asset: assets/fonts/NotoSansSC/NotoSansSC-Thin.ttf
weight: 100
- asset: assets/fonts/NotoSansSC/NotoSansSC-ExtraLight.ttf
weight: 200
- asset: assets/fonts/NotoSansSC/NotoSansSC-Light.ttf
weight: 300
- asset: assets/fonts/NotoSansSC/NotoSansSC-Regular.ttf
weight: 400
- asset: assets/fonts/NotoSansSC/NotoSansSC-Medium.ttf
weight: 500
- asset: assets/fonts/NotoSansSC/NotoSansSC-SemiBold.ttf
weight: 600
- asset: assets/fonts/NotoSansSC/NotoSansSC-Bold.ttf
weight: 700
- asset: assets/fonts/NotoSansSC/NotoSansSC-ExtraBold.ttf
weight: 800
- asset: assets/fonts/NotoSansSC/NotoSansSC-Black.ttf
weight: 900
- 然后页面上就可以使用了
fontFamilyFallback: [
'NotoSansSC',
"PingFang SC",
],
- 重启下程序,
flutter run
,查看结果,终于没有问题。
总结,其实该问题主要还是系统或者框架的支持不够,该方案还是不算最佳方案,需要引入外部字体,如果你们有更好,更方便的方案,请在文章后面评论说明,感谢!
还有,如果你们不喜欢NotoSansSC
,其他字体也是可以的,只要能够支持中文渲染,就可以。