在Flutter上显示带有表情符号的文本

use*_*522 5 emoji dart flutter

我有一些包含表情符号的文本,我试图在“文本”小部件上显示它们。但是,它们似乎显示为外来字符。Flutter是否支持显示表情符号?应该适用于iOS和Android

cod*_*ard 15

问题

不幸的是,到目前为止,Flutter 使用给定平台支持的默认表情符号。因此,在构建跨平台应用程序时,您可能会遇到在某些设备上而不是在其他设备上显示表情符号的问题。

解决方案

我解决的解决方案是使用自定义 Emoji 字体,例如Emoji OneRichText小部件,而不是基本Text小部件。

有了这个,你可以简单地拥有:

RichText(
  text: TextSpan(
    children: <TextSpan>[
      TextSpan(
        text: 'Hello',  // non-emoji characters
      ),
      TextSpan(
        text: ' ?\u200d', // emoji characters
        style: TextStyle(
          fontFamily: 'EmojiOne',
        ),
      ),
    ],
  ),
);
Run Code Online (Sandbox Code Playgroud)

通用解决方案

有了这个想法,我们甚至可以创建一个自定义小部件,给定一个字符串,构建一个RichText所有TextSpans 自动创建的对象:

class EmojiText extends StatelessWidget {

  const EmojiText({
    Key key,
    @required this.text,
  }) : assert(text != null),
       super(key: key);

  final String text;

  @override
  Widget build(BuildContext context) {
    return RichText(
      text: _buildText(this.text),
    );
  }

  TextSpan _buildText(String text) {
    final children = <TextSpan>[]; 
    final runes = text.runes;

    for (int i = 0; i < runes.length; /* empty */ ) {
      int current = runes.elementAt(i);

      // we assume that everything that is not
      // in Extended-ASCII set is an emoji...
      final isEmoji = current > 255;
      final shouldBreak = isEmoji
        ? (x) => x <= 255 
        : (x) => x > 255;

      final chunk = <int>[];
      while (! shouldBreak(current)) {
        chunk.add(current);
        if (++i >= runes.length) break;
        current = runes.elementAt(i);
      }

      children.add(
        TextSpan(
          text: String.fromCharCodes(chunk),
          style: TextStyle(
            fontFamily: isEmoji ? 'EmojiOne' : null,
          ),
        ),
      );
    }

    return TextSpan(children: children);
  } 
} 
Run Code Online (Sandbox Code Playgroud)

可以用作:

EmojiText(text: 'Hello there:  ?\u200d');
Run Code Online (Sandbox Code Playgroud)

这样做的好处是可以在您的应用程序上一致支持表情符号,您可以在不同平台上进行控制。

缺点是它会MBs向您的应用程序添加一些内容。

  • Emoji One 似乎已经成为一项名为 JoyPixels 的付费服务。我正在考虑采用上述解决方案的 Google 开源 Apache License 字体。字体称为 Noto Emoji https://github.com/googlefonts/noto-emoji (2认同)

Col*_*son 11

Flutter支持表情符号。这是一些演示表情文字输入的代码。(如果看到的是外来字符,则很可能是将字节解码为ASCII而不是UTF-8;如果您使用演示问题的代码更新问题,我们可以向您展示如何解决此问题。)

import 'dart:async';
import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

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

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

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

class _MyHomePageState extends State<MyHomePage> {
  String _message = '';

  Future<String> _promptForString(String label, { String hintText }) {
    final TextEditingController controller = new TextEditingController();
    return showDialog(
      context: context,
      child: new AlertDialog(
        title: new Text(label),
        content: new TextFormField(
          controller: controller,
          decoration: new InputDecoration(hintText: hintText),
        ),
        actions: <Widget>[
          new FlatButton(
            onPressed: () => Navigator.pop(context),
            child: const Text('CANCEL'),
          ),
          new FlatButton(
            onPressed: () => Navigator.pop(context, controller.text),
            child: const Text('OK'),
          ),
        ],
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text(_message),
      ),
      body: new Center(
        child: new Text(_message, style: Theme.of(context).textTheme.display2),
      ),
      floatingActionButton: new FloatingActionButton(
        child: new Icon(Icons.edit),
        onPressed: () async {
          String message = await _promptForString('New text', hintText: 'Try emoji!');
          if (!mounted)
            return;
          setState(() {
            _message = message;
          });
        },
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)


小智 11

您可以通过以下方式在文本字段中插入表情符号:

如果您使用的是 Mac,则可以按 Control + Command + Space。Windows 用户可以点击“Windows 键” + ; (分号)。

复制粘贴@Reso Coder https://www.youtube.com/watch?v=KfuUkq2cLZU&t=15s的说明

我在 mac 上测试过,效果很好。


Ign*_*spo 9

为了获得完整的表情符号兼容性(至少在 Android 中,并非所有表情符号都在旧操作系统版本中受支持),您可以使用 google 免费字体 Noto Color Emoji,网址为https://www.google.com/get/noto/#emoji-zsye-颜色

  • 将其添加到字体文件夹中
  • 添加到 pubspec.yaml
    fonts:
    - family: NotoEmoji
      fonts:
        - asset: fonts/NotoColorEmoji.ttf
          weight: 400
Run Code Online (Sandbox Code Playgroud)
  • 与 TextStyle 一起使用

    Text("", TextStyle(fontFamily: 'NotoEmoji'))


Shu*_*bey 6

如果您只想在文本小部件中包含表情符号,您可以从其他地方复制表情符号并将其粘贴到文本小部件中。我使用GeteMoji复制表情符号。

查看输出截图

代码:见第 8 行。

Widget build(BuildContext context) {
    return Center(
        child: Container(
            alignment: Alignment.center,
            color: Colors.deepPurple,
            //width: 200.0,
            //height: 100.0,
            child: Text("Emoji  ",
                style: TextStyle(
                  fontFamily: 'Raleway',
                  fontSize: 40,
                  decoration: TextDecoration.none,
                  color: Colors.white

                ))));
  }
Run Code Online (Sandbox Code Playgroud)