Flutter全局与局部字体(全App、全页面、单控件的设置方法) |
您所在的位置:网站首页 › 应用字体大小设置方法 › Flutter全局与局部字体(全App、全页面、单控件的设置方法) |
一、背景
项目里需要单独替换几个页面的字体。于是找到了全局指定字体的方法,参考文章:Flutter 指定字体(全局指定、局部指定),该文章提到了三种替换方法: ①全局替换,在MaterialApp的theme属性中,指定fontFamily。 ②单个替换,单独在Text的style中指定fontFamily。 ③多处替换,定义公共TextStyle ,调用它的copyWith方法。 为了方便理解,在此搬运一下: 1.全局配置— 就在主题theme中配置 MaterialApp( theme: ThemeData( fontFamily: "PingFang", // 统一指定应用的字体。 primarySwatch: Colors.green, primaryColor: Colors.white), 。。。2.局部配置—指定TextStyle中的fontFamily TextStyle( fontFamily:"PingFang", // 指定该Text的字体。 fontSize: SizeUtil.getFontSize(Dimens.font_sp12), color: CustomColors.colorPrimary, fontWeight: FontWeight.bold)3.如果多处用到指定的字体,但又不是全局用到, 你可以定义一个公共的 textStyle .如: var textFontStyle = TextStyle( fontFamily:"PingFang", // 指定该Text的字体。 ) 用到的地方用 .copyWith 这个方法, 如: Text( "显示我想要的字体", style: textFontStyle.copyWith( fontSize: 18.0, color: Colors.red, fontWeight: FontWeight.bold, ), ) TextStyle的copyWith如下: TextStyle copyWith({ bool inherit, Color color, Color backgroundColor, String fontFamily, List fontFamilyFallback, double fontSize, FontWeight fontWeight, FontStyle fontStyle, double letterSpacing, double wordSpacing, TextBaseline textBaseline, double height, Locale locale, Paint foreground, Paint background, List shadows, TextDecoration decoration, Color decorationColor, TextDecorationStyle decorationStyle, double decorationThickness, String debugLabel, })我们项目是需要替换几个页面,不是全App,第一种方法直接pass。第二种和第三种差不多,都是需要给每个Text控件设置字体,区别只是第三种不用每次指定字体名称。我们页面里面Text控件蛮多的,每个指定,也有较大的工作量。 那么,有没有单独指定某个页面的字体的方法呢? 以下是几种尝试: 二、验证后淘汰的方法 1、在页面外包裹Theme()控件(无效)全局指定的方法很眼熟,那么直接在某一块控件外,包裹一个Theme控件,不就和在MaterialApp中指定的一样吗?想到这里,我不得不佩服我的机智,这么简单的方法,居然只被我一个人想出来! 于是我兴冲冲的去尝试了,在Column控件外包裹Theme,在Theme中指定字体,期待这整个Column控件都变成我指定的字体。代码如下: @override Widget build(BuildContext context) { return Theme( data: ThemeData( fontFamily: "MaoTi", ), child: Column( children: [ Row( children: [ Text("12345"), Text("678910"), ], ), ], ) ); }然而,该方法无效,Text的字体并没有随之改变! 2、在页面外包裹MaterialApp控件(某些全局设定会冲突)MaterialApp也是一个控件,在整个页面外嵌套一层MaterialApp,然后在该MaterialApp的theme属性中设置fontFamily。代码如下: @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData( fontFamily: "MaoTi", ), home: RealPage(), ); }该方法是有效的,字体确实改变了。不过,之前的一些全局配置,比如滑动控件的波纹效果、配置的首选颜色等,被MaterialApp层拦截了,页面中使用的是Flutter默认的MaterialApp配置,没有使用整个App入口指定的配置。需要把这些全局配置重新指定一遍,才能达到一致的效果。 三、正确的使用方式 3.在Scaffold外包裹Theme控件为啥在MaterialApp的theme指定有效,直接在控件外包裹Theme控件却无效了?我感到很奇怪。查看源码,源码里也是直接用Theme包裹着child控件啊?真是太神奇了! 我注释掉部分代码,希望找到让Text字体生效的控件,经过fromwork层绕了一圈,发现生效的控件居然不在fromwork层,而是从外面传进去的!!!又经过一番排查,终于锁定,令theme生效的控件是Scaffold。 验证发现,字体是否生效与MaterialApp没有半毛钱关系,只与Scaffold有关。而Scaffold几乎是每个页面都有的,在它外层包裹Theme,指定fontFamily,即可达到单独设置某个页面的效果。而且,它不会阻隔MaterialApp中指定的全局配置,完美! @override Widget build(BuildContext context) { return Theme( data: ThemeData( fontFamily: "MaoTi", ), child: Scaffold( body: Column( children: [ Row( children: [ Text("12345"), Text("678910"), ], ), ], ) ), ); } 四、依然存在的坑Theme结合Scaffold,能指定页面级别的Text控件字体。但是,如果页面中有使用富文本,或者自定义的Text控件,字体不会生效,还得在style中单独设置。在MaterialApp的theme属性中指定fontFamily,同样会有这个问题。因为字体只和Scaffold有关,和MaterialApp没有关系。 @override Widget build(BuildContext context) { return Theme( data: ThemeData( fontFamily: "MaoTi", ), child: Scaffold( body: Center(child: Column( children: [ Row( children: [ // 富文本,ThemeData中的指定无效,需在TextStyle中单独指定 RichText( text: TextSpan( text: "123456", style: TextStyle(color: Colors.blue,fontSize: 30,fontFamily: "MaoTi",) )), // 自定义文本,同上。能不能通过改变自定义方法来使用Theme字体不太清楚,我们项目中的自定义字体需单独指定 CustomText("123456",style: TextStyle(color: Colors.red,fontFamily: "MaoTi",),) ], ), ], ) ) ), ); } 五、总结字体的指定,从大到小,目前有以下几种方法: ①全App,在MateralApp中指定,只要每个页面都有Scaffold,需注意一下富文本和自定义文本。 ②全页面,Theme结合Scaffold使用,同样需注意富文本和自定义文本。 ③多处使用,定义公共TextStyle,调用copyWith方法。 ④单个控件,直接在TextStyle中设置fontFamily。 技术是在不断发展的,我当前使用的版本是1.9,或许后面高的版本会有更多的使用方法,又或者现在我遇到的问题在高版本并不会用到,这篇文章只能提供一个思路,给大家参考,感谢阅读! 最后,也谢谢@emdd2016大大,他的文章给我指了一个验证的方向。本文只提供了使用字体的方法,引入字体的方法网上太多,不再赘述,可以自行查找。 参考文章:https://blog.csdn.net/emdd2016/article/details/93312143 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |