web-dev-qa-db-ja.com

Flutterに絵文字でテキストを表示する

絵文字を含むテキストがいくつかあり、テキストウィジェットに表示しようとしています。ただし、外国文字として表示されているようです。 Flutterは絵文字の表示をサポートしていますか? iOSとAndroidの両方で動作するはずです

5
user3217522

Flutterは絵文字をサポートしています。絵文字のテキスト入力を示すコードを次に示します。 (外国文字が表示されている場合は、バイトをUTF-8ではなくASCII)としてデコードしている可能性があります。質問を次のコードで更新すると、これを修正する方法を示すことができます。問題を示しています。)

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;
          });
        },
      ),
    );
  }
}
11
Collin Jackson

テキストウィジェットに絵文字を含めたいだけの場合は、別の場所から絵文字をコピーして、テキストウィジェット内に貼り付けることができます。 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

                ))));
  }
1
ShubhamDubey

問題

現在のところ、残念ながら、Flutterは特定のプラットフォームでサポートされているデフォルトの絵文字を使用しています。したがって、クロスプラットフォームアプリを構築するときに、特定のデバイスでは絵文字が表示され、他のデバイスでは表示されないという問題が発生する可能性があります。

ソリューション

私が解決した解決策は、基本的なRichTextウィジェットの代わりに、 Emoji OneTextウィジェットなどのカスタム絵文字フォントを使用することです。

これで、あなたは単に持つことができます:

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

一般化されたソリューション

このアイデアを使用すると、文字列を指定して、すべてのRichTextsを自動作成してTextSpanオブジェクトを作成するカスタムウィジェットを作成することもできます。

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);
  } 
} 

次のように使用できます。

EmojiText(text: 'Hello there: ???? ????️\u200d????');

これには、さまざまなプラットフォームで制御できるアプリで絵文字を一貫してサポートできるという利点があります。

欠点は、アプリにMBsが追加されることです。

1
Edward Njoroge

絵文字の完全な互換性(少なくともAndroidでは、古いOSバージョンですべての絵文字がサポートされているわけではありません)については、Googleの無料フォントであるNoto Color Emojiを https://www.google.com/get/noto/#)で使用できます。 emoji-zsye-color

  • Fontsフォルダーに追加します
  • pubspec.yamlを追加します
_    fonts:
    - family: NotoEmoji
      fonts:
        - asset: fonts/NotoColorEmoji.ttf
          weight: 400
_
  • textStyleで使用

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