30

TextDirectionのドキュメントには次のように書かれています。

Flutter は、右から左または左から右の書き込み方向を使用するかどうかにかかわらず、現在使用されている世界中の言語で記述されたアプリケーションのニーズに対応するように設計されています。Flutter は、縦書きテキストや犀形テキストなどの他の書字モードをサポートしていません。これらはコンピューター プログラムではめったに使用されないためです。(強調追加)

Flutter は縦書きテキストをサポートしていないだけでなく、将来的には正式にサポートされなくなります。これは初期の設計上の決定でした (ここここを参照)。

それでも、今日、縦書きのサポートは実際に使用されています。中国語と日本語の特定の用途に加えて、伝統的なモンゴル文字ではそれが必要です。このスクリプトは、内モンゴルのコンピューター プログラムで非常に一般的に使用されます ()。

上から下に書かれ、行は左から右に折り返されます。

ここに画像の説明を入力

さらに、絵文字と CJK 文字は、縦に表示されたときにその向きを保持します (絶対に必要というわけではありませんが、推奨されます)。以下の画像では、上の段落は現在の実装を示し、下の段落は正しい垂直レンダリングを示しています。

ここに画像の説明を入力

// sample text
ᠨᠢᠭᠡ ᠬᠣᠶᠠᠷ ᠭᠣᠷᠪᠠ ᠳᠥᠷᠪᠡ ᠲᠠᠪᠤ ᠵᠢᠷᠭᠤᠭ᠎ᠠ ᠳᠣᠯᠣᠭ᠎ᠠ ᠨᠠ‍ᠢᠮᠠ ᠶᠢᠰᠦ ᠠᠷᠪᠠ one two three four five six seven eight nine ten 汉字 한국어 モンゴル語 English? ᠮᠣᠩᠭᠣᠯ︖

Flutter は垂直スクリプトをサポートしていないため、最初から実装する必要があります。実際のテキストのレイアウトと描画はすべてLibTxtを使用して Flutter エンジンで行われるため、それを変更することはできません。

上から下への垂直の Text ウィジェットを作成するには何が必要ですか?

アップデート

私はまだ答えを探しています。レミの答えは、1 行のテキストには適していますが、複数行のテキストには適していません。

私は現在、3つの異なる可能な解決策を研究しています:

  • RichText ウィジェットに似たカスタム StatelessWidget をサポートする RenderObject サブクラス (またはおそらくRenderParagraphサブクラス) を作成します。
  • CustomPaint ウィジェットを使用する
  • ListView (テキスト行ごとに 1 行)、テキスト ウィジェット、および WidgetSpans の複合ウィジェットを作成します。

これらのすべてには、テキストの測定、レイアウト、および行のリストの取得が含まれます。

別のアップデート

私は現在、RichText と RenderParagraph を模倣するカスタム ウィジェットとレンダリング オブジェクトの作成に傾倒しています。内部では、RenderParagraph は TextPainter を使用してテキストのレイアウトとペイントを行います。私の問題は、TextPainter が基礎となる Skia LibTxt ライブラリに密接に結合されていることです。ここで、実際のレイアウトとペイントがすべて行われます。デフォルトの ltr と rtl 以外にテキストを配置することは、大きな問題であることがわかっています。

さらに別のアップデート

受け入れられた回答は、この質問で提示した基準を満たしています。短期的なニーズに対応できると思います。テキスト スタイルの適用などについてはいくつか保留がありますが、さらにテストを行う必要があります。長期的には、カスタムのテキスト レイアウトとペイントを試してみるかもしれません。

4

6 に答える 6

24

このソリューションは、フレックス ボックス レイアウトに基づいています。文字列を単語のリストに変換し、垂直方向に回転した Text ウィジェットに配置します。Wrapこれらは に設定されたウィジェットでレイアウトされAxis.verticalます。折り返しウィジェットは、単語を次の列に配置することで、折り返しが必要な単語を自動的に処理します。

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Wrap(
          direction: Axis.vertical,
          children: _getWords(),
        ),
      ),
    );
  }

  List<Widget> _getWords() {
    const text =
        "That's all  12345 One Two Three Four Five ᠸᠢᠺᠢᠫᠧᠳᠢᠶᠠ᠂ ᠴᠢᠯᠦᠭᠡᠲᠦ ᠨᠡᠪᠲᠡᠷᠬᠡᠢ ᠲᠣᠯᠢ ᠪᠢᠴᠢᠭ ᠪᠣᠯᠠᠢ᠃";
    var emoji = RegExp(r"([\u2200-\u3300]|[\uD83C-\uD83E].)");
    List<Widget> res = [];
    var words = text.split(" ");
    for (var word in words) {
      var matches = emoji.allMatches(word);
      if (matches.isEmpty) {
        res.add(RotatedBox(quarterTurns: 1, child: Text(word + ' ')));
      } else {
        var parts = word.split(emoji);
        int i = 0;
        for (Match m in matches) {
          res.add(RotatedBox(quarterTurns: 1, child: Text(parts[i++])));
          res.add(Text(m.group(0)));
        }
        res.add(RotatedBox(quarterTurns: 1, child: Text(parts[i] + ' ')));
      }
    }
    return res;
  }
}

ここに画像の説明を入力

于 2019-07-08T15:38:49.647 に答える
1

最終的に、テキストのレンダリングを処理するカスタム ウィジェットを作成しました。

ここに画像の説明を入力

それは些細な作業ではありませんでしたが、柔軟です。他の回答があなたのニーズを満たさない場合、この質問への他の訪問者は同様のパターンに従うことができます。

Flutter でのテキスト レンダリングをより詳細に制御したい場合は、Flutter での最初の失望を読んで、この GitHub の問題にコメントを追加してください。

于 2020-02-11T00:52:23.440 に答える