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

如何在Flutter TextView的动态字符串中自动检测超链接?

Flutter 无第三方TextView包实现文本超链接自动检测方案

核心逻辑完全依赖Flutter内置组件实现,无需引入任何第三方文本渲染类依赖包。

实现思路

通过正则表达式匹配文本中所有符合规则的URL片段,将整段文本切割为普通文本片段和链接文本片段,再通过RichText组件组合不同样式的TextSpan完成渲染,链接片段可通过内置手势识别器绑定点击事件。

步骤1:定义URL匹配正则

可根据业务需求调整正则规则,示例正则可匹配带http/https协议和不带协议的常规域名:

final RegExp urlRegExp = RegExp(
  r'(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)',
  caseSensitive: false,
);

步骤2:构建带可点击链接的富文本组件

以下是完整封装的示例组件代码:

import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
// 若需要跳转链接可引入官方维护的url_launcher包,不属于第三方text view类包,无需可删除
// import 'package:url_launcher/url_launcher.dart';

class AutoLinkText extends StatelessWidget {
  final String content;
  final TextStyle normalStyle;
  final TextStyle linkStyle;

  const AutoLinkText({
    super.key,
    required this.content,
    this.normalStyle = const TextStyle(color: Colors.black, fontSize: 14),
    this.linkStyle = const TextStyle(color: Colors.blue, fontSize: 14, decoration: TextDecoration.underline),
  });

  @override
  Widget build(BuildContext context) {
    List<TextSpan> spans = [];
    int currentPos = 0;
    final matches = urlRegExp.allMatches(content);

    for (final match in matches) {
      // 匹配到链接之前的普通文本
      if (match.start > currentPos) {
        spans.add(TextSpan(
          text: content.substring(currentPos, match.start),
          style: normalStyle,
        ));
      }
      // 链接文本
      final url = match.group(0)!;
      spans.add(TextSpan(
        text: url,
        style: linkStyle,
        recognizer: TapGestureRecognizer()
          ..onTap = () {
            // 这里处理链接点击逻辑,比如跳转链接
            debugPrint('点击了链接:$url');
            // 若使用url_launcher跳转可放开以下代码
            // launchUrl(Uri.parse(url.startsWith('http') ? url : 'https://$url'));
          },
      ));
      currentPos = match.end;
    }
    // 剩余的普通文本
    if (currentPos < content.length) {
      spans.add(TextSpan(
        text: content.substring(currentPos),
        style: normalStyle,
      ));
    }

    return RichText(text: TextSpan(children: spans));
  }
}

步骤3:直接调用组件即可

在社交帖子视图中直接传入用户发布的内容即可自动识别链接:

AutoLinkText(content: '这是用户发布的内容,包含链接baidu.com,还有https://flutter.dev可以点击')

可选优化点

  • 可调整正则规则,增加对@用户、#话题、邮箱、手机号等特殊内容的匹配,复用相同的切割逻辑实现多类型内容识别
  • 可自定义链接的长按事件,实现复制链接、打开等更多操作
  • 若不需要识别不带协议的域名,可删除正则中(https?:\/\/)?的可选匹配部分,仅识别带明确协议的链接

内容的提问来源于stack exchange,提问作者Phyoe Ko

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 01:54:05