Flutter - 用小部件替换子字符串

Flutter - Replace a subsstring with a Widget

我正在构建一个带有 flutter 的应用程序,但我在使用我的一个小部件时遇到了一些问题。我从 API 端点收到 JSON 响应,以便在帖子上建立评论,但我需要能够获取字符串的一部分并将其包装在 GestureDetector 中,为了处理“@提及”。

例如:我有字符串 hey there @MattChris how are you? 我需要能够将 @MattChris 包装在 GestureDetector.

目前,我解析传入的字符串并提供一个列表,其中包含来自实际评论的每个 space 分隔的单词。像这样:

List<Widget> comment = new List();

outer: for (String word in json['content'].toString().split(" ")) {
  if (word != null && word.isNotEmpty) {
    if (word.startsWith('@')) {

      comment.add(GestureDetector(
        onTap: goToProfile,
        child: Text(word + ' ')
      );

    } else {
      comment.add(Text(word + ' '));
    }
  }
}

现在唯一的问题是有很多额外的元素占用了内存,而且很难确保文本以我期望的方式换行。我已经看到答案 here,但我不确定如何确保文本换行,就好像它是 Text 小部件中的一个字符串一样。

我找到了可行的解决方案。再次阅读我喜欢的实现,并查看评论,我决定使用递归函数:

List<TextSpan> _mentionParser(String message, Iterable<dynamic> mentions) {
  if (message == null || message.isEmpty) // Don't return anything if there is no message.
    return [];

  for (Map<String, dynamic> mention in mentions) { // Loop through the list of names to replace
    if (message.contains("@${mention['username']}")) { // If the message contains the name to replace
      List<TextSpan> _children = [];
      String preUsernameMessage = message.substring(0, message.indexOf("@${mention['username']}")).trimLeft(); // Get everything before the mention
      if (preUsernameMessage != null && preUsernameMessage.isNotEmpty)
        _children.add(TextSpan(children: _mentionParser(preUsernameMessage, mentions))); // if it isn't empty, recurse and add to the list

      _children.add( // Always add the display name to the list
        TextSpan(
          text: "${mention['display_name']}".trim(),
          style: TextStyle(color: Color(0xff2e6da4)),
          recognizer: TapGestureRecognizer()
            ..onTap = () => {gotoProfile(json['username'])}
        )
      );

      String postUsernameMessage = message.substring(message.indexOf("@${mention['username']}") + "@${mention['username']}".length, message.length).trimRight(); // Get everything after the mention
      if (postUsernameMessage != null && postUsernameMessage.isNotEmpty) // If it isn't empty, recurse and add it to the list
        _children.add(TextSpan(children: _mentionParser(postUsernameMessage, mentions)));

      return _children; // return the constructed list
    }
  }
  return [TextSpan(text: message)]; // If the string didn't contain any of the strings to replace, then just return the message as passed.
}

然后我将其称为 Text.richTextSpan 上的 children 变量。这花了一些时间,但我能够让实施工作!

public String method(String str) {
if (str != null && str.length() > 0 && str.charAt(str.length() - 1) == 'x') {
    str = str.substring(0, str.length() - 1);
}
return str; // to remove last character
}