You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Text.rich使用阿拉伯语文本时WidgetSpan渲染顺序反转问题

绿色容器本应在对应位置,实际出现顺序错位

问题复现

在Flutter中使用Text.rich组件搭配阿拉伯语等RTL(从右到左)方向文本时,嵌入的WidgetSpan组件渲染顺序和代码定义顺序不一致,出现错位问题,复现代码如下:

Text.rich(
  TextSpan(
    children: [
      TextSpan(text: 'بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.green,
          child: Text('1'),
        ),
      ),
      TextSpan(text: 'ٱلۡحَمۡدُ لِلَّهِ رَبِّ ٱلۡعَٰلَمِينَ'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.blue,
          child: Text('2'),
        ),
      ),
      TextSpan(text: 'ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.red,
          child: Text('3'),
        ),
      ),
    ],
  ),
  textDirection: TextDirection.rtl,
)
问题原因

Flutter富文本排版遵循Unicode双向文本(Bidi)规则:阿拉伯语属于强RTL方向字符,排版逻辑正常,但WidgetSpan属于中性方向占位元素,不会被自动标记RTL排版属性,在RTL语境下会被引擎按照LTR顺序排列,最终出现错位。

解决方案

二选一即可:

  • 方案1:保留Text.rich结构,给每个WidgetSpan前后添加强方向控制字符,强制指定占位元素的排版方向,修改后示例:
Text.rich(
  TextSpan(
    children: [
      TextSpan(text: 'بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      // 添加强RTL方向标记
      const TextSpan(text: '\u202B'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.green,
          child: Text('1'),
        ),
      ),
      // 终止方向标记作用范围
      const TextSpan(text: '\u202C'),
      TextSpan(text: 'ٱلۡحَمۡدُ لِلَّهِ رَبِّ ٱلۡعَٰلَمِينَ'),
      const TextSpan(text: '\u202B'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.blue,
          child: Text('2'),
        ),
      ),
      const TextSpan(text: '\u202C'),
      TextSpan(text: 'ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      const TextSpan(text: '\u202B'),
      WidgetSpan(
        child: Container(
          width: 30,
          height: 30,
          color: Colors.red,
          child: Text('3'),
        ),
      ),
      const TextSpan(text: '\u202C'),
    ],
  ),
  textDirection: TextDirection.rtl,
)
  • 方案2:绕开富文本双向排版逻辑,使用Wrap组件实现文本和组件混排,适合嵌入组件交互逻辑复杂的场景:
Directionality(
  textDirection: TextDirection.rtl,
  child: Wrap(
    crossAxisAlignment: WrapCrossAlignment.center,
    children: [
      const Text('بِسۡمِ ٱللَّهِ ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      Container(
        width: 30,
        height: 30,
        color: Colors.green,
        child: const Text('1'),
      ),
      const Text('ٱلۡحَمۡدُ لِلَّهِ رَبِّ ٱلۡعَٰلَمِينَ'),
      Container(
        width: 30,
        height: 30,
        color: Colors.blue,
        child: const Text('2'),
      ),
      const Text('ٱلرَّحۡمَٰنِ ٱلرَّحِيمِ'),
      Container(
        width: 30,
        height: 30,
        color: Colors.red,
        child: const Text('3'),
      ),
    ],
  ),
)

提示:使用Wrap方案时可通过SizedBox手动调整文本和组件的间距,对齐效果和Text.rich基线对齐基本一致。

内容的提问来源于stack exchange,提问作者Hakim Hüseyin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 01:24:34