如何动态更改文本字段中特定文本的颜色?

时间:2019-09-08 06:30:34

标签: flutter

考虑波纹管图像,我想根据文本字段中的用户输入文本(而非整个文本)动态更改部分文本的文本颜色。我该怎么办? enter image description here

4 个答案:

答案 0 :(得分:1)

由于TextField小部件只能一次显示一种样式,因此除非Flutter正式发布重大更改以进行更改,否则无法实现多种样式。

我们本可以制作自己的Textfield小部件,但这会使我的回答比人们期望的更长。实际上,我可以制作一个专用于多样式Textfield的程序包,然后在答案中共享它的链接。

解决方案:

  

pub.dev上有一个软件包可以部分解决您的问题。

     

https://pub.dev/packages/zefyr

     

截至目前可用的最佳迷你文档:

     

https://medium.com/@pulyaevskiy/zefyr-0-3-embedding-and-decorating-456e634449a6

您可能会觉得这对于您要实现的目标来说太复杂了,但这是目前唯一可用的东西。

提示:不要忘了用ZefyrEditorZefyrScaffold包裹起来。

答案 1 :(得分:1)

在此示例中,我们实际上不需要完整的富文本编辑器。

在我的应用中,我有一个类似的目标,即突出显示标签(@flutter)或日期引用(next weekon Friday等),并且通过扩展内置在EditableText小部件中并将我的示例作为要点发布在这里:https://gist.github.com/pulyaevskiy/d7af7217c2e71f31dfb78699f91dfbb5

下面是此小部件的完整实现,我称为AnnotatedEditableText。 有一个新的属性annotations,该属性描述了需要突出显示的文本范围及其样式。

import 'package:flutter/widgets.dart';

class Annotation extends Comparable<Annotation> {
  Annotation({@required this.range, this.style});
  final TextRange range;
  final TextStyle style;

  @override
  int compareTo(Annotation other) {
    return range.start.compareTo(other.range.start);
  }

  @override
  String toString() {
    return 'Annotation(range:$range, style:$style)';
  }
}

class AnnotatedEditableText extends EditableText {
  AnnotatedEditableText({
    Key key,
    FocusNode focusNode,
    TextEditingController controller,
    TextStyle style,
    ValueChanged<String> onChanged,
    ValueChanged<String> onSubmitted,
    Color cursorColor,
    Color selectionColor,
    TextSelectionControls selectionControls,
    this.annotations,
  }) : super(
          key: key,
          focusNode: focusNode,
          controller: controller,
          cursorColor: cursorColor,
          style: style,
          keyboardType: TextInputType.text,
          autocorrect: true,
          autofocus: true,
          selectionColor: selectionColor,
          selectionControls: selectionControls,
          onChanged: onChanged,
          onSubmitted: onSubmitted,
        );

  final List<Annotation> annotations;

  @override
  AnnotatedEditableTextState createState() => new AnnotatedEditableTextState();
}

class AnnotatedEditableTextState extends EditableTextState {
  @override
  AnnotatedEditableText get widget => super.widget;

  List<Annotation> getRanges() {
    var source = widget.annotations;
    source.sort();
    var result = new List<Annotation>();
    Annotation prev;
    for (var item in source) {
      if (prev == null) {
        // First item, check if we need one before it.
        if (item.range.start > 0) {
          result.add(new Annotation(
            range: TextRange(start: 0, end: item.range.start),
          ));
        }
        result.add(item);
        prev = item;
        continue;
      } else {
        // Consequent item, check if there is a gap between.
        if (prev.range.end > item.range.start) {
          // Invalid ranges
          throw new StateError(
              'Invalid (intersecting) ranges for annotated field');
        } else if (prev.range.end < item.range.start) {
          result.add(Annotation(
            range: TextRange(start: prev.range.end, end: item.range.start),
          ));
        }
        // Also add current annotation
        result.add(item);
        prev = item;
      }
    }
    // Also check for trailing range
    final String text = textEditingValue.text;
    if (result.last.range.end < text.length) {
      result.add(Annotation(
        range: TextRange(start: result.last.range.end, end: text.length),
      ));
    }
    return result;
  }

  @override
  TextSpan buildTextSpan() {
    final String text = textEditingValue.text;

    if (widget.annotations != null) {
      var items = getRanges();
      var children = <TextSpan>[];
      for (var item in items) {
        children.add(
          TextSpan(style: item.style, text: item.range.textInside(text)),
        );
      }
      return new TextSpan(style: widget.style, children: children);
    }

    return new TextSpan(style: widget.style, text: text);
  }
}

答案 2 :(得分:0)

富文本控制器工作正常!

https://pub.dev/packages/rich_text_controller上查看更多

example using rich text controller

首先你选择你的 RegExp

RichTextController _controller;

  Map<RegExp, TextStyle> patternUser = {
    RegExp(r"\B@[a-zA-Z0-9]+\b"):
        TextStyle(color: Colors.amber, fontWeight: FontWeight.bold)
  };

在 initState() 上

 _controller = RichTextController(
      patternMap: patternUser,

    );

在 TextFormField 上添加控制器

  TextFormField(
     controller: _controller,
     style: TextStyle(color: Colors.white),
   )

答案 3 :(得分:-1)

您可以在Text Widget中使用简单的样式

Text("value",style: TextStyle(color: Colors.purple)),

或者如果您想为一行中的特定值着色,则使用具有多个TextWidgets的行并给出其中一种颜色 例子

 Row(children: <Widgets>[
      Text("see this")),
      Text("@tammyDelgado",style: TextStyle(color: Colors.purple)),
      Text("Wonderfull")),
    ]),