Flutter 搜索关键字标红

场景

搜索信息;结果中含输入关键字标红显示;(包含数字,英文)
方法1、连续命中关键字标红;
方法2、判断只要包含单独字符就标红;

首先前提:通过富文本展示

RichText(
    maxLines: 1,
    overflow: TextOverflow.ellipsis,
    text: TextSpan(
    children: getTextSpanList('xxxxx展示文案',
    fontSize: 30,
    searchKey: searchKeyWords)))

判断是否高亮

List<TextSpan> getTextSpanList(String textContent,
    {String searchKey = '',//关键字
    String frontContent = '', //展示内容
    double fontSize = 15.0, //默认自豪感
    FontWeight fontWeight = FontWeight.w500, //默认自重
    Color fontColor = ColorConstant.blackTextColor,//展示颜色
    Color selectFontColor = ColorConstant.redTextColor,//命中颜色
    bool singleLine = true}) {
  List<TextSpan> textSpanList = List();

  TextStyle styleNormal = TextStyle(
    fontSize: fontSize,
    color: fontColor,
    fontWeight: fontWeight,
    fontFamily: 'PingFangSC-Medium');

  TextStyle styleLight = TextStyle(
      fontSize: fontSize,
      color: selectFontColor,
      fontWeight: fontWeight,
      fontFamily: 'PingFangSC-Medium');

  if (frontContent.isEmpty == false) {
    textSpanList.add(TextSpan(
        text: frontContent,
        style: styleNormal));
  }

   ///拆分字符判断高亮展示
  if (null != searchKey && searchKey.isNotEmpty) {
    List<Map> _strMapList =
        CompareStrUtil.getHighLightDifferent(searchKey, textContent);
    _strMapList?.forEach((map) {
      textSpanList.add(TextSpan(
          text: map['content'],
          style: map['isHighlight'] ? styleLight : styleNormal));
    });
  } else {
    textSpanList.add(TextSpan(text: textContent, style: styleNormal));
  }

  //TODO 连续命中高亮方式先保留
  // if (searchKey != null &&
  //     searchKey.isNotEmpty &&
  //     (textContent.contains(searchKey) ||
  //         textContent.toLowerCase().contains(searchKey.toLowerCase()))) {
  //   List<Map> _strMapList = CompareStrUtil.getHighLightDifferent('速9','速度与激情9');
    // bool _isContains = true;
    // while (_isContains) {
    //   int startIndex = textContent.indexOf(searchKey) == -1
    //       ? textContent.toLowerCase().indexOf(searchKey.toLowerCase())
    //       : textContent.indexOf(searchKey);
    //   String showStr =
    //       textContent.substring(startIndex, startIndex + searchKey.length);
    //   Map _strMap;
    //   if (startIndex > 0) {
    //     String normalStr = textContent.substring(0, startIndex);
    //     _strMap = Map();
    //     _strMap['content'] = normalStr;
    //     _strMap['isHighlight'] = false;
    //     _strMapList.add(_strMap);
    //   }
    //   _strMap = Map();
    //   _strMap['content'] = showStr;
    //   _strMap['isHighlight'] = true;
    //   _strMapList.add(_strMap);
    //   textContent = textContent.substring(
    //       startIndex + searchKey.length, textContent.length);
    //
    //   _isContains = textContent.contains(searchKey);
    //   if (!_isContains && textContent != '') {
    //     _strMap = Map();
    //     _strMap['content'] = textContent;
    //     _strMap['isHighlight'] = false;
    //     _strMapList.add(_strMap);
    //   }
    // }
  //   _strMapList.forEach((map) {
  //     textSpanList.add(TextSpan(
  //       text: map['content'],
  //       style: map['isHighlight'] ? styleLight : styleNormal
  //     ));
  //   });
  // } else {
  //   ///正常显示所有文字
  //   textSpanList.add(TextSpan(
  //     text: textContent,
  //     style: styleNormal));
  // }
  return textSpanList;
}
class CompareStrUtil {

  static List<Map> getHighLightDifferent(String a, String b) {
    List<String> temp = getDiff(a, b);
    // List<Map> result = getHighLight(a, temp[0]);
    List<Map> result = getHighLight(b, temp[1]);
    return result;
  }

  static List<Map> getHighLight(String source, String temp) {
    List<Map> _strMapList = List();
    List<String> sourceChars = List();
    for (int i = 0; i < source.length; i++) {
      sourceChars.add(source[i]);
    }
    List<String> tempChars = List();
    for (int i = 0; i < temp.length; i++) {
      tempChars.add(temp[i]);
    }
    Map _strMap;
    bool flag = false;
    for (int i = 0; i < sourceChars.length; i++) {
      if (tempChars[i] != '*') {
        if (i == 0) {
          _strMap = Map();
          _strMap['content'] = sourceChars[i];
          _strMap['isHighlight'] = false;
          _strMapList.add(_strMap);
        } else if (flag) {
          _strMap = Map();
          _strMap['content'] = sourceChars[i];
          _strMap['isHighlight'] = false;
          _strMapList.add(_strMap);
        } else {
          _strMap = Map();
          _strMap['content'] = sourceChars[i];
          _strMap['isHighlight'] = false;
          _strMapList.add(_strMap);
        }
        flag = true;
      } else if (flag == true) {
        _strMap = Map();
        _strMap['content'] = sourceChars[i];
        _strMap['isHighlight'] = true;
        _strMapList.add(_strMap);
        flag = false;
      } else {
        _strMap = Map();
        _strMap['content'] = sourceChars[i];
        _strMap['isHighlight'] = true;
        _strMapList.add(_strMap);
      }
    }
    return _strMapList;
  }

  static List<String> getDiff(String a, String b) {
    List<String> result;
    //选取长度较小的字符串用来穷举子串
    if (a.length < b.length) {
      result = getDiff1(a, b, 0, a.length);
    } else {
      result = getDiff1(b, a, 0, b.length);
      result = [result[1], result[0]];
    }
    return result;
  }

  //将a的指定部分与b进行比较生成比对结果
  static List<String> getDiff1(String a, String b, int start, int end) {
    //忽略大小写比较
    a = a.toLowerCase();
    b = b.toLowerCase();
    List<String> result = [a, b];
    int len = result[0].length;
    while (len > 0) {
      for (int i = start; i < end - len + 1; i++) {
        String sub = result[0].substring(i, i + len);
        int idx = -1;
        if ((idx = result[1].indexOf(sub)) != -1) {
          result[0] = setEmpty(result[0], i, i + len);
          result[1] = setEmpty(result[1], idx, idx + len);
          if (i > 0) {
            //递归获取空白区域左边差异
            result = getDiff1(result[0], result[1], 0, i);
          }
          if (i + len < end) {
            //递归获取空白区域右边差异
            result = getDiff1(result[0], result[1], i + len, end);
          }
          len = 0; //退出while循环
          break;
        }
      }
      len = len ~/ 2;
    }
    return result;
  }

  //将字符串s指定的区域设置成空格
  static String setEmpty(String s, int start, int end) {
    List<String> array = [];
    for (int i = 0; i < s.length; i++) {
      array.add(s[i]);
    }
    for (int i = start; i < end; i++) {
      array[i] = '*';
    }
    return array.join();
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值