flutter_kinetra/lib/kt_widgets/kt_high_light_text.dart
2025-09-12 14:19:13 +08:00

244 lines
6.2 KiB
Dart

import 'package:flutter/material.dart';
class KtTextHighlightUtils {
/// 高亮搜索结果(支持正则匹配)
static TextSpan highlightSearchResult({
required String text,
required String searchTerm,
TextStyle? normalStyle,
TextStyle? highlightStyle,
bool caseSensitive = false,
}) {
if (searchTerm.isEmpty ||
!text.toLowerCase().contains(searchTerm.toLowerCase())) {
return TextSpan(text: text, style: normalStyle);
}
final matches = RegExp(
searchTerm,
caseSensitive: caseSensitive,
).allMatches(text);
final List<TextSpan> children = [];
int lastEnd = 0;
for (final match in matches) {
// 添加匹配前的文本
if (match.start > lastEnd) {
children.add(
TextSpan(
text: text.substring(lastEnd, match.start),
style: normalStyle,
),
);
}
// 添加匹配的文本(高亮) - 修改为文本颜色区分
children.add(
TextSpan(
text: text.substring(match.start, match.end),
style:
highlightStyle ??
TextStyle(
color: Colors.blue, // 默认使用蓝色文本
fontWeight: FontWeight.bold,
),
),
);
lastEnd = match.end;
}
// 添加剩余的文本
if (lastEnd < text.length) {
children.add(TextSpan(text: text.substring(lastEnd), style: normalStyle));
}
return TextSpan(children: children);
}
/// 高亮文本(简单子字符串匹配)
static TextSpan highlightText({
required String text,
required String keyword,
Color highlightColor = Colors.blue, // 修改为文本颜色
Color textColor = Colors.black,
double fontSize = 16,
FontWeight normalWeight = FontWeight.normal,
FontWeight highlightWeight = FontWeight.bold,
bool caseSensitive = false,
String? fontFamily,
}) {
if (keyword.isEmpty) {
return TextSpan(
text: text,
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontWeight: normalWeight,
),
);
}
final String searchText = caseSensitive ? text : text.toLowerCase();
final String searchKeyword = caseSensitive
? keyword
: keyword.toLowerCase();
if (!searchText.contains(searchKeyword)) {
return TextSpan(
text: text,
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontWeight: normalWeight,
fontFamily: fontFamily,
),
);
}
final List<TextSpan> children = [];
int startIndex = 0;
while (startIndex < text.length) {
final int matchIndex = searchText.indexOf(searchKeyword, startIndex);
if (matchIndex == -1) {
// 剩余文本无匹配,全部添加
children.add(
TextSpan(
text: text.substring(startIndex),
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontWeight: normalWeight,
fontFamily: fontFamily,
),
),
);
break;
}
// 添加匹配前的文本
if (matchIndex > startIndex) {
children.add(
TextSpan(
text: text.substring(startIndex, matchIndex),
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontWeight: normalWeight,
fontFamily: fontFamily,
),
),
);
}
// 添加匹配的文本(高亮) - 修改为文本颜色区分
children.add(
TextSpan(
text: text.substring(matchIndex, matchIndex + keyword.length),
style: TextStyle(
color: highlightColor, // 使用指定的高亮文本颜色
fontSize: fontSize,
fontWeight: highlightWeight,
fontFamily: fontFamily,
),
),
);
// 更新起始位置
startIndex = matchIndex + keyword.length;
}
return TextSpan(children: children);
}
/// 高亮多个关键词
static TextSpan highlightMultipleKeywords({
required String text,
required List<String> keywords,
Color highlightColor = Colors.blue, // 修改为文本颜色
Color textColor = Colors.black,
double fontSize = 16,
String? fontFamily,
}) {
if (keywords.isEmpty || text.isEmpty) {
return TextSpan(
text: text,
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontFamily: fontFamily,
),
);
}
// 创建一个包含所有关键词的正则表达式
final regexPattern = keywords.map(RegExp.escape).join('|');
final regex = RegExp(regexPattern, caseSensitive: false);
final matches = regex.allMatches(text);
if (matches.isEmpty) {
return TextSpan(
text: text,
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontFamily: fontFamily,
),
);
}
final List<TextSpan> children = [];
int lastEnd = 0;
for (final match in matches) {
// 添加匹配前的文本
if (match.start > lastEnd) {
children.add(
TextSpan(
text: text.substring(lastEnd, match.start),
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontFamily: fontFamily,
),
),
);
}
// 添加匹配的文本(高亮) - 修改为文本颜色区分
children.add(
TextSpan(
text: text.substring(match.start, match.end),
style: TextStyle(
color: highlightColor, // 使用指定的高亮文本颜色
fontSize: fontSize,
fontWeight: FontWeight.bold,
fontFamily: fontFamily,
),
),
);
lastEnd = match.end;
}
// 添加剩余的文本
if (lastEnd < text.length) {
children.add(
TextSpan(
text: text.substring(lastEnd),
style: TextStyle(
color: textColor,
fontSize: fontSize,
fontFamily: fontFamily,
),
),
);
}
return TextSpan(children: children);
}
}