场景
搜索信息;结果中含输入关键字标红显示;(包含数字,英文)
方法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();
}
}