Flutter 实现高亮显示搜索结果的文字

一:设计思路

因为要在一行内容中显示不同颜色的文本,所以要用到 RichText 组件;
如果没有找到要高亮显示的文本则返回原字符串;
如果找到了要高亮显示的文本,则从字符串左边开始截取,当出现第一个要高亮显示的文本时,把此时已经出现的普通文本和高亮显示的文本都加入到一个 List 的数组中,如果字符串中有多个符合条件的文本,重复前面出现第一个要高亮显示的文本时的步骤即可。

class LightText extends StatelessWidget {
  final String text; // 要显示的内容
  final String lightText; // 要显示的内容中,需要高亮显示的文字(默认为空字符串,即不高亮显示文本)
  final TextStyle? textStyle; // 要显示的内容的文本风格
  final TextStyle? lightStyle; // 要显示的内容中,需要高亮显示的文字的文本风格

  // 默认普通文本的样式
  TextStyle _defTextStyle = TextStyle(fontSize: 16, color: Colors.black);
  // 默认高亮文本的样式
  TextStyle _defLightStyle = TextStyle(fontSize: 16, color: Colors.blue);

  LightText({
    required this.text,
    this.lightText = "",
    this.textStyle,
    this.lightStyle,
  });

  @override
  Widget build(BuildContext context) {
    // 如果没有需要高亮显示的内容
    if (lightText.isEmpty) {
      return Text(text, style: textStyle ?? _defTextStyle);
    }
    // 如果有需要高亮显示的内容
    return _lightView();
  }

  /// 需要高亮显示的内容
  Widget _lightView() {
    List spans = [];
    int start = 0; // 当前要截取字符串的起始位置
    int end; // end 表示要高亮显示的文本出现在当前字符串中的索引

    // 如果有符合的高亮文字
    while ((end = text.indexOf(lightText, start)) != -1) {
      // 第一步:添加正常显示的文本
      spans.add(TextSpan(text: text.substring(start, end), style: textStyle ?? _defTextStyle));
      // 第二步:添加高亮显示的文本
      spans.add(TextSpan(text: lightText, style: lightStyle ?? _defLightStyle));
      // 设置下一段要截取的开始位置
      start = end + lightText.length;
    }
    // 下面这行代码的意思是
    // 如果没有要高亮显示的,则start=0,也就是返回了传进来的text
    // 如果有要高亮显示的,则start=最后一个高亮显示文本的索引,然后截取到text的末尾
    spans.add(
      TextSpan(text: text.substring(start, text.length), style: textStyle ?? _defTextStyle),
    );
    
    return RichText(
      text: TextSpan(children: spans),
    );
  }
}

作者:AllenSu
链接:https://juejin.cn/post/7082956142065745933
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

你可能感兴趣的:(Flutter 实现高亮显示搜索结果的文字)