如何通过TapGestureRecognizer获取有关TextSpan的信息

时间:2018-07-18 14:38:37

标签: flutter flutter-layout

我正在尝试为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';
    }
  }

}

1 个答案:

答案 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,因此在声明其上已附加此手势识别器时,您可以随意使用跨度-因此,您可以自由保留所需的信息并将其传递给识别器。