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

Flutter中如何实现RTL文本右对齐、LTR文本左对齐?

我之前也碰到过类似的多语言排版坑,尤其是RTL文本对齐的问题,给你几个不用flutter_markdown的靠谱解决方案:

方案1:SelectableText.rich + Directionality 自动适配方向

这个方案能帮你保留原文本格式(换行、空格),同时自动识别RTL/LTR语言并调整对齐方式。核心是用unicode_bidi包检测文本主导方向,再用Directionality包裹段落实现正确对齐。

首先添加依赖:

dependencies:
  unicode_bidi: ^0.3.10

然后封装方向检测工具和文本组件:

// 检测文本方向的工具函数
TextDirection detectTextDirection(String text) {
  final bidi = UnicodeBidi(text);
  return bidi.direction == Direction.RTL ? TextDirection.rtl : TextDirection.ltr;
}

// 构建多语言预格式化文本
Widget buildMultiLangPreText(String rawText) {
  // 按空行拆分段落(适配Word粘贴的格式)
  final paragraphs = rawText.split('\n\n');
  
  return Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: paragraphs.map((paragraph) {
      final textDirection = detectTextDirection(paragraph);
      return Directionality(
        textDirection: textDirection,
        child: SelectableText(
          paragraph,
          style: const TextStyle(
            whiteSpace: WhiteSpace.pre, // 强制保留原格式的换行、空格
            fontSize: 14,
          ),
        ),
      );
    }).toList(),
  );
}

调用时直接传入你的多语言文本即可:

buildMultiLangPreText("""
This is English LTR text, it should stay left-aligned.

هذا نص عربي يجب أن يكون محاذياً لليمين بشكل تلقائي.

Another LTR paragraph with multiple spaces    and line breaks.
""")
方案2:自定义可复用组件

如果需要在多个地方使用,把上面的逻辑封装成自定义组件,用起来更省心:

class PreformattedMultiLangText extends StatelessWidget {
  final String text;
  final TextStyle? style;

  const PreformattedMultiLangText({
    super.key,
    required this.text,
    this.style,
  });

  @override
  Widget build(BuildContext context) {
    final paragraphs = text.split('\n\n');
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: paragraphs.map((paragraph) {
        final direction = detectTextDirection(paragraph);
        return Directionality(
          textDirection: direction,
          child: SelectableText(
            paragraph,
            style: style?.copyWith(whiteSpace: WhiteSpace.pre) ??
                const TextStyle(whiteSpace: WhiteSpace.pre),
          ),
        );
      }).toList(),
    );
  }

  TextDirection detectTextDirection(String text) {
    final bidi = UnicodeBidi(text);
    return bidi.direction == Direction.RTL ? TextDirection.rtl : TextDirection.ltr;
  }
}

使用示例:

PreformattedMultiLangText(
  text: yourMultiLangRawText,
  style: const TextStyle(fontSize: 16, color: Colors.black87),
)
方案3:处理带格式的文本(粗体/斜体)

如果从Word粘贴的文本包含粗体、斜体这类格式,可以简单解析后用Text.rich结合InlineSpan实现,同时保留方向适配。比如解析**粗体**标记:

List<InlineSpan> parseFormattedSpans(String text) {
  final boldRegex = RegExp(r'\*\*(.*?)\*\*');
  final spans = <InlineSpan>[];
  int lastPosition = 0;

  for (final match in boldRegex.allMatches(text)) {
    if (match.start > lastPosition) {
      spans.add(TextSpan(text: text.substring(lastPosition, match.start)));
    }
    spans.add(TextSpan(
      text: match.group(1),
      style: const TextStyle(fontWeight: FontWeight.bold),
    ));
    lastPosition = match.end;
  }

  if (lastPosition < text.length) {
    spans.add(TextSpan(text: text.substring(lastPosition)));
  }
  return spans;
}

然后把这个解析结果放到Directionality包裹的Text.rich里,同样设置whiteSpace: WhiteSpace.pre即可。

这些方案都不用依赖flutter_markdown,而且能完美保留原文本格式,自动处理RTL文本的右对齐问题,我自己用这套逻辑处理过阿拉伯语、英语混合的文本,稳定性很高。

内容的提问来源于stack exchange,提问作者Faisal Afroz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:44:09