我正在尝试为Flutter中的嵌入式链接制作一个小部件。为此,我正在制作一个名为EmbeddedUrlText的小部件,它接受一个字符串。对于超链接,我在文本周围添加了一个标签,该标签需要突出显示为链接。我正在使用RichText小部件,其中包含文本范围。链接(TextSpans)具有一个TapGestureRecognizer,可监听点击。我想在TextSpan中获取文本,或以某种方式获取单击哪个文本跨度。
该小部件将被称为
EmbeddedUrlText("This is the <l>link</l>", ["https://www.google.com"])
因此,当点击“链接”一词时,google.com将打开。链接的索引将打开相应的链接索引。
到目前为止,如果已给出链接列表,则链接将突出显示并显示,如果指定的索引也将打开,但TapGestureRecognizer不会返回单击WHICH文本跨度的任何信息。请提出我可以的任何建议。
以下是小部件的代码:
class EmbeddedUrlText extends StatelessWidget {
List<TextSpan> widgets = [];
//Keeps a count of the number of links in the text.
var linksAdded = 0;
EmbeddedUrlText(String text, List<String> links,
{TextStyle style = const TextStyle(color: Colors.black)}) {
//Find text between <l></l> tags and add it as a separate text span
String widgetText = "";
for (var i = 0; i < text.length; i++) {
// Beyond this limit, a complete <l> tag cannot fit, hence do not check for tags.
if (i < text.length - 6) {
if (text[i] == "<" && text[i + 1] == "l" && text[i + 2] == ">") {
widgets.add(TextSpan(
text: widgetText, style: TextStyle(color: Colors.black)));
widgetText = "";
i += 3;
while (text[i] != "<" && i < text.length) {
widgetText = widgetText + text[i];
i++;
}
i += 3;
widgets.add(
TextSpan(
style: TextStyle(color: Colors.blue),
text: widgetText,
recognizer: TapGestureRecognizer()..onTap = () {
//I want to open URL of the clicked index of TextSpan
}
)
);
widgetText = "";
} else {
widgetText = widgetText + text[i];
}
} else {
widgetText = widgetText + text[i];
}
}
// At the end add the remaining text to the text
widgets.add(TextSpan(text: widgetText, style: TextStyle(color: Colors.black)));
}
@override
Widget build(BuildContext context) {
return RichText(text: TextSpan(children: widgets));
}
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
答案 0 :(得分:0)
您正在为每个跨度创建一个新的唯一的TapGestureRecognizer
。如果您想让识别器区分跨度,我想您可以跟踪在当前跨度之前发现了多少跨度。在代码中,通过添加currentIndex
:
class EmbeddedUrlText extends StatelessWidget {
List<TextSpan> widgets = [];
//Keeps a count of the number of links in the text.
var linksAdded = 0;
EmbeddedUrlText(String text, List<String> links,
{TextStyle style = const TextStyle(color: Colors.black)}) {
//Find text between <l></l> tags and add it as a separate text span
String widgetText = "";
int currentIndex = 0;
for (var i = 0; i < text.length; i++) {
// Beyond this limit, a complete <l> tag cannot fit, hence do not check for tags.
if (i < text.length - 6) {
if (text[i] == "<" && text[i + 1] == "l" && text[i + 2] == ">") {
widgets.add(TextSpan(
text: widgetText, style: TextStyle(color: Colors.black)));
widgetText = "";
i += 3;
while (text[i] != "<" && i < text.length) {
widgetText = widgetText + text[i];
i++;
}
i += 3;
widgets.add(
TextSpan(
style: TextStyle(color: Colors.blue),
text: widgetText,
recognizer: TapGestureRecognizer()..onTap = () {
//Also have logic for exceeding the array bounds
_launchURL(links[currentIndex]);
}
)
);
widgetText = "";
currentIndex = currentIndex + 1;
} else {
widgetText = widgetText + text[i];
}
} else {
widgetText = widgetText + text[i];
}
}
// At the end add the remaining text to the text
widgets.add(TextSpan(text: widgetText, style: TextStyle(color: Colors.black)));
}
@override
Widget build(BuildContext context) {
return RichText(text: TextSpan(children: widgets));
}
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
我可能错误地理解了问题,但是我认为当时您希望TapGestureRecognizer
为您提供有关跨度的一些信息。由于这是声明性UI,因此在声明其上已附加此手势识别器时,您可以随意使用跨度-因此,您可以自由保留所需的信息并将其传递给识别器。