import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class LinkText extends StatelessWidget {
final String text;
final TextStyle? style;
final TextStyle? linkStyle;
const LinkText({
super.key,
required this.text,
this.style,
this.linkStyle,
});
@override
Widget build(BuildContext context) {
// 🔥【超严格正则】能识别 http/https/www/普通域名,且不会误判普通文字
final regExp = RegExp(
r'''(https?:\/\/[^\s]+)|''' // http/https 链接
r'''(www\.[a-z0-9\-]+\.[^\s]+)|''' // www 开头链接
r'''([a-z0-9\-]+\.(com|cn|net|org|io|app|dev|top|xyz|cc|co|gov|edu)(\/[^\s]*)?)''', // 纯域名(不带http/www)
caseSensitive: false,
);
final List<TextSpan> children = [];
final matches = regExp.allMatches(text);
int start = 0;
for (final match in matches) {
// 普通文本
if (match.start > start) {
children.add(TextSpan(
text: text.substring(start, match.start),
style: style,
));
}
// 链接文本
final link = text.substring(match.start, match.end);
children.add(TextSpan(
text: link,
style: linkStyle ??
const TextStyle(
color: Colors.blue,
decoration: TextDecoration.underline,
height: 1.3,
),
recognizer: TapGestureRecognizer()..onTap = () => _openUrl(link),
));
start = match.end;
}
// 剩余文本
if (start < text.length) {
children.add(TextSpan(
text: text.substring(start),
style: style,
));
}
return RichText(
text: TextSpan(
style: style ??
const TextStyle(
color: Colors.black87,
fontSize: 15,
),
children: children,
),
);
}
// 打开链接(自动补全协议)
Future<void> _openUrl(String url) async {
String targetUrl = url;
if (!url.startsWith(RegExp(r'https?://'))) {
targetUrl = 'https://$url';
}
final uri = Uri.parse(targetUrl);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
}
}
}
超链接识别,http开头和不是http开头常用的一些
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。