Nas*_*sky 5 emoji dart flutter
我想使用 Flutter 在文本小部件中显示表情符号。
\n\n当我从互联网复制示例表情符号时,其中一些在我的 IDE 中显示为 2 个字符。
\n\n例如:
\n\nstatic String dualCharEmoji = "\xe2\x9a\x94\xef\xb8\x8f";\nstatic String singleCharEmoji = "";\nRun Code Online (Sandbox Code Playgroud)\n\n当我在文本小部件中使用此变量时,它们都工作正常:
\n\nText("\xe2\x9a\x94\xef\xb8\x8f",)\nText("",)\nRun Code Online (Sandbox Code Playgroud)\n\n但是,仅在首次运行应用程序时,双字符表情符号仅显示为其第一个字符。
\n\n即仅当第一次打开应用程序时,剑图标显示为\xe2\x9a\x94而不是\xe2\x9a\x94\xef\xb8\x8f
重新加载后,它会得到修复,并且热重新加载/热重启不会再次导致错误。
\n\n我的问题是:
\n\n这是一个错误吗?我在这里遗漏了一些细节吗?为什么只有第一次打开应用程序时才会出现这种情况?
\n\n如何从一开始就显示 2 尺寸的表情符号?
\n\n我正在使用以下 Flutter 版本:
\n\n>flutter --version\nFlutter 1.9.1+hotfix.4 \xe2\x80\xa2 channel stable \xe2\x80\xa2 https://github.com/flutter/flutter.git\nFramework \xe2\x80\xa2 revision cc949a8e8b (9 weeks ago) \xe2\x80\xa2 2019-09-27 15:04:59 -0700\nEngine \xe2\x80\xa2 revision b863200c37\nTools \xe2\x80\xa2 Dart 2.5.0\nRun Code Online (Sandbox Code Playgroud)\n\n请参阅下面的最小可重现示例:
\n\nimport \'package:flutter/material.dart\';\n\nvoid main() => runApp(MyApp());\n\nclass MyApp extends StatelessWidget {\n Widget build(BuildContext context) {\n return MaterialApp(\n title: \'Flutter Demo\',\n home: MyHomePage(),\n );\n }\n}\n\nclass MyHomePage extends StatefulWidget {\n MyHomePage({Key key}) : super(key: key);\n\n @override\n _MyHomePageState createState() => _MyHomePageState();\n}\n\nclass _MyHomePageState extends State<MyHomePage> {\n static String dualCharEmoji = "\xe2\x9a\x94\xef\xb8\x8f";\n static String singleCharEmoji = "";\n String text = dualCharEmoji;\n int count = 0;\n void swapText() {\n setState(() {\n if (count % 2 == 0)\n text = singleCharEmoji;\n else\n text = dualCharEmoji;\n count++;\n });\n }\n\n @override\n Widget build(BuildContext context) {\n return Scaffold(\n body: Center(\n child: Column(\n mainAxisAlignment: MainAxisAlignment.center,\n children: <Widget>[\n Text(\n text,\n style: TextStyle(fontSize: 50),\n ),\n ],\n ),\n ),\n floatingActionButton: FloatingActionButton(\n onPressed: swapText,\n ),\n );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
在创建这个问题、进行多次不成功的尝试并且没有有效答案之后,我在 Flutter 的官方 Github 存储库上创建了一个问题。
在我展示了我的问题后,一位用户解释说,这是与 Flutter 如何渲染和缓存字体相关的错误,以防默认字体无法正确处理某些字符:
第一次渲染 DualCharEmoji 时,Flutter 发现默认字体无法处理 2694 个字符。[...]它可以渲染基本的 2694 交叉剑角色,但不能渲染 2694 FE0F 表情符号。
当渲染 singleCharEmoji 时,Flutter 现在将 NotoSansSymbols 字体包含在提供给 HarfBuzz 文本整形器的字体列表中。[...] 并且 matchFamilyStyleCharacter 返回 NotoColorEmoji。Flutter 也会将此字体添加到缓存中。
下次引擎尝试渲染 DualCharEmoji 时,它会向 HarfBuzz 提供两种缓存字体(NotoSansSymbols 和 NotoColorEmoji)。现在 HarfBuzz 知道了 NotoColorEmoji 中定义的序列,它可以识别 2694 FE0F 表情符号并将其返回给 Flutter。
我在这里仅引用了讨论的某些部分。您可以在我上面链接的问题页面上阅读完整的讨论和解释。
用户提出了一些解决方法,即两个:
首先,您可以强制引擎预先缓存正确处理表情符号的字体。build您可以通过在、 或方法中添加以下代码initState(在构建文本小部件之前运行的任何位置)来完成此操作:
import 'dart:ui';
ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(locale: window.locale));
pb.addText('\ud83d\ude01'); // smiley face emoji
pb.build().layout(ParagraphConstraints(width: 100));
Run Code Online (Sandbox Code Playgroud)
这适用于我的示例项目,但如问题页面所述:
然而,这依赖于当前 Flutter 文本引擎的实现细节,这些细节将来可能会发生变化。
因此请注意,此解决方法可能会在任何给定时间停止工作。
第二种解决方法如下:
目前的解决方法是在文本样式中列出所需的字体,它将被正确解析。
这只是TextStyle为 Text Widget 提供一个属性,并设置其fontFamily(或fontFamilyFallback)属性。所选字体必须已经支持所需的所有字符。这也对我有用,但是我必须包含来自我的计算机(或来自公共在线包)的自定义字体。
| 归档时间: |
|
| 查看次数: |
1318 次 |
| 最近记录: |