flutter取消动态字体大小

文章目录

如果接触过原生开发的朋友可能知道

最初几年官方推荐使用 sp 作为字体大小的单位,但是事实上经过长时间实践的情况下,大家都开始逐渐使用 dp 作为单位

这样使用者调整系统字体大小,app 中的文字大小就不会受到影响,出现错误等情况

flutter 中修改

iOS 中叫动态字体大小,对应辅助功能中的字体大小

20190312152451.png

android 中叫字体大小

20190312152635.png

当你开发完成,又遇到用户修改系统字体大小导致某些地方错位,甚至按钮被挤出屏幕看不见了就是个问题了

而 flutter 中没有单位的概念,我们应该如何实现这个功能呢

在 flutter 中,是由 MediaQuery 来实现对应功能的

1var data = MediaQuery.of(context);
2data.textScaleFactor; //这个就是对应的动态字体大小,我们只需要『修改』这个值就可以了

修改自然是不可能的,这东西都是 final 的,我们要做的就是 flutter 中的通用做法

 1class NoScaleTextWidget extends StatelessWidget {
 2  final Widget child;
 3
 4  const NoScaleTextWidget({
 5    Key key,
 6    @required this.child,
 7  }) : super(key: key);
 8
 9  @override
10  Widget build(BuildContext context) {
11    return MaxScaleTextWidget(
12      max: 1.0,
13      child: child,
14    );
15  }
16}
17
18class MaxScaleTextWidget extends StatelessWidget {
19  final double max;
20  final Widget child;
21
22  const MaxScaleTextWidget({
23    Key key,
24    this.max = 1.2,
25    @required this.child,
26  }) : super(key: key);
27
28  @override
29  Widget build(BuildContext context) {
30    var data = MediaQuery.of(context);
31    var scale = math.min(max, data.textScaleFactor);
32    return MediaQuery(
33      data: data.copyWith(textScaleFactor: scale),
34      child: child,
35    );
36  }
37}

我这里的做法就是这样,创建一个组件,在内部修改这个值,然后把你的控件『包』起来

这里可以是你的 Scaffold,Text 等等的 widget

不过这样要修改的地方太多,而且后面不好改

我们可以用一个小技巧,使用 MaterialApp 的 builder 属性

 1class MyApp extends StatefulWidget {
 2  @override
 3  _MyAppState createState() => _MyAppState();
 4}
 5
 6class _MyAppState extends State<MyApp> {
 7  @override
 8  Widget build(BuildContext context) {
 9    return MaterialApp(
10      ....
11      builder: (ctx, w) {
12        return MaxScaleTextWidget(
13            max: 1.0,
14            child: w,
15        );
16      },
17    );
18  }
19}

在这个 builder 中这么写,就可以修改你 app 中的所有控件不受动态字体大小的影响了

我在 github 有一个 也可查看到代码,需要自备梯子

后记

动态字体的事情就是这样了