带超链接的Flutter TextField



我想创建一个文本字段,用户应该能够在文本框中输入超链接,超链接的颜色是蓝色的,超链接是可点击的。

是否有任何可用的包或任何方法来实现它。请帮助!

这些包可以帮助你做到这一点。

link_text

flutter_linkify

当然可以-您可以使用LinkText包:https://pub.dev/packages/link_text

首先更新pubspec.yaml:

dependencies: 
link_text: ^0.2.0

:

final String _hyperlink = 'StackOverflow https://stackoverflow.com/';
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: LinkText(
_hyperlink,
textAlign: TextAlign.left,
),
),
);
}

这使用了将RichText小部件放在不可见的TextField之上的hack解决方案:

import 'package:flutter/material.dart';
import 'package:link_text/link_text.dart';
import 'package:transparent_pointer/transparent_pointer.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
TextEditingController textCont = TextEditingController();
class _MyHomePageState extends State<MyHomePage> {
@override
void initState() {
textCont.addListener(() {
setState(() {});
});
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Center(
child: Stack(
children: [
TextField(
maxLines: null,
decoration: null,
controller: textCont,
autofocus: true,
style: TextStyle(
letterSpacing: 0,
fontSize: 24,
height: null,
color: Colors.transparent,
)),
TransparentPointer(
child: LinkText(
textCont.text,
textStyle:
TextStyle(fontSize: 24, height: null, letterSpacing: 0),
linkStyle: TextStyle(
fontSize: 24,
color: Colors.blue,
letterSpacing: 0,
height: null),
onLinkTap: (link) async {
final Uri _url = Uri.parse(link);
await launchUrl(_url, mode: LaunchMode.externalApplication);
},
),
),
],
)),
),
);
}
}

它使用已经存在的https://pub.dev/packages/link_text包来解析文本并返回一个RichText span,其中url是可点击的链接。透明指针(https://pub.dev/packages/transparent_pointer)小部件通过点击手势通过堆栈传递,所以你仍然可以与LinkText小部件下面的TextField进行交互。

LinkText有点不灵活,所以要更改url的样式,您必须fork它并编辑源代码。它用来检测url的RegEx也有一些限制,它要求所有的url都以http://或https://.开头Linkify可能是一个更好的解决方案,但我发现它处理人性化链接和样式url的方式使得它不可能轻松地与下面不可见的TextField对齐。

编辑:

如果你要尝试这个,也值得注意的是,上述解决方案的工作,你将不得不修改link_text包添加一个空白字符到所有的换行,由于一个bug(?)在如何RichText呈现空行与Text: https://github.com/flutter/flutter/issues/121715

最新更新