如何在 Flutter 中制作多种颜色的 TextField

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

你可以进行更复杂的处理。例如,我们通过解析语法树并对关键字、字面量、注释等进行不同的着色,来制作代码高亮:

我们首先导入为另一个项目制作的 highlightingflutter_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/flutter-code-editor-19e0090a62cc


原文:https://medium.com/akvelon/how-to-make-textfield-in-multiple-colors-in-flutter-c317ae0efafe

相关推荐
恋猫de小郭3 小时前
2026 Flutter VS React Native ,同时在 AI 时代 VS Native 开发,你没见过的版本
android·前端·flutter
明君879978 小时前
Flutter 如何给图片添加多行文字水印
前端·flutter
四眼肥鱼16 小时前
flutter 利用flutter_libserialport 实现SQ800 串口通信
前端·flutter
火柴就是我1 天前
让我们实现一个更好看的内部阴影按钮
android·flutter
王晓枫1 天前
flutter接入三方库运行报错:Error running pod install
前端·flutter
shankss2 天前
Flutter 下拉刷新库 pull_to_refresh_plus 设计与实现分析
flutter
忆江南2 天前
iOS 深度解析
flutter·ios
明君879972 天前
Flutter 实现 AI 聊天页面 —— 记一次 Markdown 数学公式显示的踩坑之旅
前端·flutter
恋猫de小郭2 天前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
MakeZero2 天前
Flutter那些事-交互式组件
flutter