富文本中添加字体选项功能
A little extra help for styling your text
样式设置方面的一些额外帮助
I recently learned about a little known corner of the Flutter world: Font Features. I’ll share that with you today. Keep it in the back of your mind and when you need it, just do a search for Flutter Font Features. You’ll probably end up back here because there isn’t much out there about Font Features except for the documentation, and even that is a little sparse.
我最近了解了Flutter世界的一个鲜为人知的角落:字体功能。 今天我将与您分享。 记住它,当您需要时,只需搜索Flutter Font Features即可 。 您可能最终会回到这里,因为除文档外,关于Font Features的内容并不多,甚至还很少。
更改字体 (Changing the font)
This article isn’t primarily about changing the font family, but since it is related to fonts, I’ll start by briefly reviewing how to use different fonts in your app.
本文主要不是改变字体,但由于它关系到字体,我将简要回顾如何在你的应用程序中使用不同的字体启动。
系统字体 (System fonts)
The default font on Android is Roboto
and on iOS it is .SF UI Display
or .SF UI Text
(SF meaning San Francisco). If you want to use a different font, then you will need to add it to your app.
Android上的默认字体是Roboto
,而iOS上的默认字体是.SF UI Display
或.SF UI Text
(SF表示旧金山)。 如果要使用其他字体,则需要将其添加到您的应用程序中。


They look the same to me.
他们对我来说看起来一样。
您自己的自定义字体 (Your own custom fonts)
I’ve written before about how to add your own custom font to your project, so I won’t go into detail, but the basic process is the following:
之前我已经写过关于如何向您的项目中添加自己的自定义字体的文章,因此我将不做详细介绍,但是其基本过程如下:
- Add a font to your assets folder. 将字体添加到资产文件夹。
2. Register the font in pubspec.yaml.
2.在pubspec.yaml中注册字体。
flutter:
fonts:
- family: MyFont
fonts:
- asset: assets/my_font.ttf
3. Use the font in your code by specifying the fontFamily
.
3.通过指定fontFamily
在代码中使用字体。
Text(
'Hello world',
style: TextStyle(
fontFamily: 'MyFont',
),
)

Google字体包 (Google fonts package)
Now we have the google_fonts package that makes things even easier. With just a few lines of code you have almost a thousand different open source fonts available to you.
现在,我们有了google_fonts软件包,它使事情变得更加轻松。 仅需几行代码,您就可以使用近千种不同的开源字体。
Add the google_fonts dependency to your pubspec.yaml file:
将google_fonts依赖项添加到您的pubspec.yaml文件中:
dependencies:
google_fonts: ^0.3.8
Then use whatever font you want in your code:
然后在代码中使用所需的任何字体:
import 'package:google_fonts/google_fonts.dart';
Text(
'Hello world',
style: GoogleFonts.pinyonScript(
fontSize: 50,
),
),

Notes:
笔记:
You can browse the different fonts here. When you find one you like, just note the name and in your code write
GoogleFonts.someFontName()
.您可以在此处浏览不同的字体。 找到喜欢的名字后,只需记下名字,然后在代码中写
GoogleFonts.someFontName()
。By default the fonts are downloaded the first time you use the app. That may leave a few seconds on the first run where a default font is shown before it switches to your custom font. If you don’t like that, you can bundle the font with the app. There are directions for how to do that here.
默认情况下,首次使用该应用程序时会下载字体。 这可能会在第一次运行时留下几秒钟的时间,在此之前显示默认字体,然后再切换到自定义字体。 如果您不喜欢,可以将字体与应用程序捆绑在一起。 有关于如何做到这一点的方向在这里 。
Let’s get on to Font Features now. Unfortunately, it turns out that you can’t use Font Features with the Google fonts because that information has been stripped from these fonts. (On the other hand, this keeps the font size smaller.) If you want to use a Font Feature, you will either have to use the default system font or add your own custom font.
现在让我们开始使用字体功能。 不幸的是,事实证明您无法将字体功能与Google字体一起使用,因为该信息已从这些字体中删除。 (另一方面,这使字体大小变小。)如果要使用字体功能,则必须使用默认系统字体或添加自己的自定义字体。
字体功能 (Font Features)
Font Features allow you to tweak the default behavior of a font. There are many different features. I’ll give a few different examples so you can get a feel for what they do.
字体功能使您可以调整字体的默认行为。 有许多不同的功能。 我将给出一些不同的示例,以便您可以了解它们的功能。
表格与比例图 (Tabular vs Proportional Figures)
Have a look at the following animation:
看看以下动画:

Note how the width of the bottom line jitters in and out. That can be really annoying when you are trying to create a stable UI layout. The reason for the variable width is that the font glyphs are using a proportional width (proportionalFigures
). That is, each number and letter has a different width. The top line on the other hand has the font set to tabularFigures
, or in other words, monospace, even though it isn’t a monospace font.
请注意底线的宽度如何抖动。 当您尝试创建稳定的UI布局时,这可能真的很烦人。 可变宽度的原因是字体字形使用的是比例宽度( proportionalFigures
图形)。 即,每个数字和字母具有不同的宽度。 另一方面,顶行将字体设置为tabularFigures
,换句话说,将其设置为等宽字体,即使它不是等宽字体也是如此。
Here is the code:
这是代码:
Text(
'There are ${_value.toInt()} cars.',
style: TextStyle(
fontFeatures: [
FontFeature.tabularFigures(),
]
),
),
Text(
'There are ${_value.toInt()} cars.',
style: TextStyle(
fontFeatures: [
FontFeature.proportionalFigures(),
]
),
),
The full code is here. (For some reason the DartPad version doesn’t show proportional figures, so I just gave you the GitHub gist link. You can paste it into an Android or iOS project to test it.)
完整的代码在这里 。 (由于某种原因,DartPad版本没有显示比例数字,所以我只是给了您GitHub gist链接。您可以将其粘贴到Android或iOS项目中进行测试。)
常规数与旧式数 (Regular vs Oldstyle numbers)
Old style numbers are sometimes short or written below the baseline. You can see them on the second line of the following image.
旧样式编号有时会短一些或写在基线以下。 您可以在下图的第二行看到它们。

To get them, you can can use FontFeature.oldstyleFigures()
as in the following example:
要获取它们,可以使用FontFeature.oldstyleFigures()
如以下示例所示:
Text(
'0123456789',
),
Text(
'0123456789',
style: TextStyle(
fontFeatures: [
FontFeature.oldstyleFigures(),
],
),
),
减零 (Slashed zero)
Supposedly using FontFeature.slashedZero()
should give you a slashed zero, but I was only able to achieve it using FontFeature.stylisticSet(6)
. This is demonstrated by the following image and code. The fact that slashedZero
didn’t work could be a bug in Flutter or a problem with the font.
假设使用FontFeature.slashedZero()
应该给您一个零斜线,但是我只能使用FontFeature.stylisticSet(6)
来实现。 下面的图像和代码对此进行了演示。 slashedZero
的事实可能是Flutter中的错误或字体问题。

Text(
'0',
),
Text(
'0',
style: TextStyle(
fontFeatures: [
FontFeature.slashedZero(),
],
),
),
Text(
'0',
style: TextStyle(
fontFeatures: [
FontFeature.stylisticSet(6),
],
),
),
Note: FontFeature.stylisticSet(n)
takes an integer n
from 1 to 20. The different sets have variations on the font glyphs. However, I found so little variation in the system font that it wasn’t even worth showing you.
注意: FontFeature.stylisticSet(n)
取1到20之间的整数n
。不同的集合在字体字形上有所不同。 但是,我发现系统字体变化很小,甚至不值得向您展示。
随机变化 (Randomized variations)
This one seems really interesting. The problem was I couldn’t find a free font to demonstrate it. Leave a comment if you know one.
这个似乎真的很有趣。 问题是我找不到免费字体来演示它。 如果您知道,请发表评论。
The idea here is that a handwriting font could be made to look more real by having several variations for each glyph. These glyph variations could then be randomly shown. This is demonstrated in the following image:
这里的想法是,通过对每个字形进行多种变体,可以使手写字体看起来更真实。 然后可以随机显示这些字形变化。 下图演示了这一点:

If you had a font that supported this, you could theoretically get the randomized variations with the following code:
如果您拥有支持此功能的字体,则理论上可以使用以下代码获得随机变化:
Text(
'Anna meets Otto',
style: TextStyle(
fontFamily: 'Some handwriting font',
fontFeatures: [
FontFeature.randomize(),
],
),
),
其他字体功能 (Other font features)
The font features I showed above are predefined in Flutter, but there are many, many, many, many, many more. You can access them by using a four-letter code with FontFeature.enable('xxxx')
where xxxx
is where the code string goes. For example, FontFeature.tabularFigures()
is equivalent to FontFeature.enable('tnum')
.
的字体特性我发现上面颤振是预定义的,但也有很多 , 很多 , 很多 , 很多 , 很多更多。 您可以通过在FontFeature.enable('xxxx')
中使用四个字母的代码来访问它们,其中xxxx
是代码字符串所在的位置。 例如, FontFeature.tabularFigures()
等同于FontFeature.enable('tnum')
。
Take a look at a few examples. The example image is first and the code to produce it comes after.
看几个例子。 首先是示例图像,然后是生成它的代码。

Text(
'Small Caps',
style: TextStyle(
fontFeatures: [
FontFeature.enable('smcp'),
],
),
),

Text(
'Subscript',
style: TextStyle(
fontFeatures: [
FontFeature.enable('subs'),
],
),
),

Text(
'Superscript',
style: TextStyle(
fontFeatures: [
FontFeature.enable('sups'),
],
),
),

Text(
'1/2 3/4 27/56',
style: TextStyle(
fontFeatures: [
FontFeature.enable('frac'),
],
),
),

Text(
'你爱我吗',
style: TextStyle(
fontFeatures: [
FontFeature.enable('trad'),
],
),
),
(That one converted simplified Chinese to traditional characters.)
(那个人将简体中文转换为繁体字。)
多种字体功能 (Multiple Font Features)
As you’ve noticed, fontFeatures
takes a list of FontFeature
. Supposedly this means you can combine multiple effects that make sense to go together. However, when I tested that, it didn’t work for me:
您已经注意到, fontFeatures
一个FontFeature
列表。 据说这意味着您可以组合多种有意义的效果一起使用。 但是,当我对其进行测试时,它对我不起作用:

Text(
'1/2 Cup Flour',
style: TextStyle(
fontFeatures: [
FontFeature.enable('frac'),
FontFeature.enable('smcp'),
],
),
),
You can still use multiple Font Features, though, if you use TextSpans.
但是,如果使用TextSpans,则仍然可以使用多个字体功能。

Text.rich(
TextSpan(
children: [
TextSpan(
text: '1/2',
style: TextStyle(
fontFeatures: [
FontFeature.enable('frac'),
],
),
),
TextSpan(
text: ' Cup Flour',
style: TextStyle(
fontFeatures: [
FontFeature.enable('smcp'),
],
),
),
],
),
),
Thanks to Simon Lightfoot for the idea of using TextSpans.
感谢 Simon Lightfoot 提出使用TextSpans的想法。
结论 (Conclusion)
Font Features don’t make huge changes to your font, but they can be very useful for some situations. I was making an audio player widget recently that showed the current playtime. Without using tabularFigures
, it was a mess. Font Features solved the problem.
字体功能不会对字体进行大的更改,但是在某些情况下它们可能非常有用。 我最近制作了一个音频播放器小部件,用于显示当前播放时间。 不使用tabularFigures
,那是一团糟。 字体功能解决了这个问题。
If you notice any mistakes or a change in how Font Features are handled, please leave a comment below.
如果您发现任何错误或字体功能的处理方式发生变化,请在下面发表评论。
By the way, all of the Fonts in the image at the top were Google fonts.
顺便说一句,顶部图像中的所有字体都是Google字体。
翻译自: https://medium.com/flutter-community/font-features-in-flutter-320222fc171d
富文本中添加字体选项功能