TextField
widget 本身并不施加任何样式。相反,它会要求 TextEditingController
生成一个样式化的 TextSpan
对象,即一段带有样式的文本。
TextField
将其样式传递给 TextEditingController
,默认实现只是将其放入 TextSpan
对象中,这就是通常应用颜色的方式。
要重载该方法,请子类化 TextEditingController
并重载该方法:
dart
class GradientTextEditingController extends TextEditingController {
@override
TextSpan buildTextSpan({
required BuildContext context,
TextStyle? style,
bool? withComposing,
}) {
style ??= const TextStyle();
final leftStyle = style.copyWith(color: Colors.red);
final rightStyle = style.copyWith(color: Colors.indigo);
final children = <TextSpan>[];
for (final char in text.characters) {
children.add(
TextSpan(
text: char,
style: TextStyle.lerp(
leftStyle,
rightStyle,
children.length / text.length,
),
),
);
}
return TextSpan(style: style, children: children);
}
}
请参阅此处的完整代码。
https://gist.github.com/alexeyinkin/ee65ed81913c8962c2d19e28e11cb262
你可以进行更复杂的处理。例如,我们通过解析语法树并对关键字、字面量、注释等进行不同的着色,来制作代码高亮:
我们首先导入为另一个项目制作的 highlighting 和 flutter_highlighting 包:
dart
import 'package:flutter_highlighting/themes/vs.dart';
import 'package:highlighting/highlighting.dart';
import 'package:highlighting/languages/java.dart';
然后我们解析文本并得到语法树的简单形式:
dart
class SyntaxTextEditingController extends TextEditingController {
@override
TextSpan buildTextSpan({
required BuildContext context,
TextStyle? style,
bool? withComposing,
}) {
final highlighted = highlight.parse(text, languageId: java.id);
return TextSpan(
style: style,
children: _buildList(
nodes: highlighted.nodes,
styles: vsTheme, // Built-in theme from flutter_highlighting
ancestorStyle: style,
),
);
}
// ...
接下来是遍历语法树并为每个节点返回 TextSpan
:
dart
List<TextSpan>? _buildList({
required List<Node>? nodes,
required Map<String, TextStyle> styles,
TextStyle? ancestorStyle,
}) {
return nodes
?.map(
(node) => _buildNode(
node: node,
styles: styles,
ancestorStyle: ancestorStyle,
),
)
.toList(growable: false);
}
TextSpan _buildNode({
required Node node,
required Map<String, TextStyle> styles,
TextStyle? ancestorStyle,
}) {
final style = styles[node.className] ?? ancestorStyle;
return TextSpan(
text: node.value,
children: _buildList(
nodes: node.children,
styles: styles,
ancestorStyle: style,
),
style: style,
);
}
请参阅此处的完整代码。
https://gist.github.com/alexeyinkin/bff79a057cbf04ecd5166243d06f1d44
因此,TextEditingController
类是实现各种自定义功能的大门。我们在这条路上走得更远,并制作了一个可以做到这一点的高级代码编辑器:
如果您有兴趣,请查看这里。
原文:https://medium.com/akvelon/how-to-make-textfield-in-multiple-colors-in-flutter-c317ae0efafe