这个想法是使用自定义
TextEditingController
来覆盖 buildTextSpan
方法。然后,您可以返回自己的 TextSpan
,对部分文本使用不同的样式。
这只是一个如何实现这一目标的最小示例。请注意,您可能还需要在重写方法中实现原始
buildTextSpan
的其他一些方面。
class HighlightRange {
final int start;
final int end;
final Color color;
HighlightRange({required this.start, required this.end, required this.color});
}
class CustomTextEditingController extends TextEditingController {
List<HighlightRange> ranges = [
HighlightRange(start: 11, end: 18, color: Colors.orange),
HighlightRange(start: 31, end: 43, color: Colors.green),
];
TextStyle _getHighlightStyle(HighlightRange range) {
return TextStyle(
decoration: TextDecoration.underline,
decorationColor: range.color,
);
}
@override
TextSpan buildTextSpan({
required BuildContext context,
TextStyle? style,
required bool withComposing,
}) {
List<InlineSpan> children;
if (ranges.isEmpty) {
children = [TextSpan(text: text)];
} else {
children = [
TextSpan(text: text.substring(0, ranges.first.start)),
TextSpan(
text: text.substring(ranges.first.start, ranges.first.end),
style: _getHighlightStyle(ranges.first),
),
];
for (int i = 1; i < ranges.length; i++) {
children.addAll([
TextSpan(text: text.substring(ranges[i - 1].end, ranges[i].start)),
TextSpan(
text: text.substring(ranges[i].start, ranges[i].end),
style: _getHighlightStyle(ranges[i]),
),
]);
}
children.add(TextSpan(text: text.substring(ranges.last.end)));
}
return TextSpan(
style: TextStyle(color: Colors.black),
children: children,
);
}
}
在您的状态下使用自定义控制器类定义控制器
StatefulWidget
:
final controller = CustomTextEditingController();
您可以访问
ranges
属性:
controller.ranges = // Do something with it