Flutter中初始化时表情符号错误的文本小部件

我想使用Flutter在文本小部件中显示表情符号。

当我从互联网上复制示例表情符号时,其中的一些在我的IDE中显示为2个字符。

例如:

static String dualCharEmoji = "⚔️";
static String singleCharEmoji = "?";

当我在文本小部件中使用此变量时,它们两个都可以正常工作:

Text("⚔️",)
Text("?",)

但是,仅在首次运行应用程序时,双字符表情符号仅显示为其第一个字符。

即仅在首次打开应用程序时,剑图标才会显示为而不是⚔️

重新加载后,它得到修复,并且热重新加载/热重启不会使其再次出错。

我的问题是:

这是一个错误吗?我在这里错过了一些细节吗?为什么只有在首次打开应用程序时才会发生这种情况?

如何从一开始显示2号大小的表情符号?

我正在使用以下Flutter版本:

>flutter --version
Flutter 1.9.1+hotfix.4 • channel stable • https://github.com/flutter/flutter.git
Framework • revision cc949a8e8b (9 weeks ago) • 2019-09-27 15:04:59 -0700
Engine • revision b863200c37
Tools • Dart 2.5.0

请参见下面的最小可重复示例:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',home: MyHomePage(),);
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  static String dualCharEmoji = "⚔️";
  static String singleCharEmoji = "?";
  String text = dualCharEmoji;
  int count = 0;
  void swapText() {
    setState(() {
      if (count % 2 == 0)
        text = singleCharEmoji;
      else
        text = dualCharEmoji;
      count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
            Text(
              text,style: TextStyle(fontSize: 50),),],floatingactionButton: FloatingactionButton(
        onpressed: swapText,);
  }
}
scscsc1980 回答:Flutter中初始化时表情符号错误的文本小部件

创建了这个问题,尝试了许多失败之后,并且工作答案,我在Flutter的官方Github存储库中创建了issue

在我展示了我的问题之后,一位用户解释说,这是一个与Flutter如何呈现和缓存字体有关的错误,如果默认字体不能正确处理某些字符,则该错误:

  

首次呈现dualCharEmoji的Flutter发现默认字体无法处理2694字符。它可以渲染基本的2694交叉剑人物,但不能渲染2694 FE0F表情符号。

     

呈现singleCharEmoji时,Flutter现在将NotoSansSymbols字体包含在提供给HarfBuzz文本成形器的字体列表中。[...]并且matchFamilyStyleCharacter返回NotoColorEmoji。 Flutter还会将此字体添加到缓存中。

     

引擎下次尝试渲染dualCharEmoji时,会向HarfBuzz提供两种缓存的字体(NotoSansSymbols和NotoColorEmoji)。现在,HarfBuzz知道了NotoColorEmoji中定义的序列,它可以识别2694 FE0F表情并将其返回给Flutter。

我在这里仅讨论的某些部分。您可以在我上面链接的问题页面上阅读完整的讨论和解释。

用户建议了一些解决方法,即两个:

首先,您可以强制引擎预先缓存可正确处理表情符号的字体。您可以通过在buildinitState方法(在构建Text Widget之前运行的任何位置)中添加以下代码来做到这一点:

import 'dart:ui';

ParagraphBuilder pb = ParagraphBuilder(ParagraphStyle(locale: window.locale));
pb.addText('\ud83d\ude01');  // smiley face emoji
pb.build().layout(ParagraphConstraints(width: 100));

这在我的示例项目中有效,但如“问题”页面上所述:

  

但是,这取决于当前Flutter文本引擎的实现细节,将来可能会更改。

因此请注意,此解决方法可能会在任何给定时间停止工作。

第二种解决方法如下:

  

目前的解决方法是以文本样式列出所需的字体,它将正确解析。

只需将TextStyle属性(设置为fontFamily(或fontFamilyFallback)赋予Text Widget。所选字体必须已经支持所需的所有字符。这对我也有用,但是我必须从计算机(或公共的在线软件包)中添加自定义字体。

本文链接:https://www.f2er.com/3017265.html

大家都在问