TextField中文本的样式部分

时间:2019-02-11 04:01:17

标签: flutter

我正在实现一个自定义文本字段,并且我希望在用户键入某些关键字(即主题标签)的样式时,使用与其余文本不同的样式。

这样的:

enter image description here

在Flutter中有办法做到这一点吗?

4 个答案:

答案 0 :(得分:1)

TextField不提供该功能。

https://pub.dartlang.org/packages/zefyr可以做到。

答案 1 :(得分:1)

这个问题与How to change color of particular text in a text field dynamically?

非常相似

我在https://stackoverflow.com/a/57846261/5280562

中回答了

简而言之:您可以扩展EditableText小部件,包括其EditableTextState类,并覆盖buildTextSpan方法。

下面是一个在我的应用中使用的名为AnnotatedEditableText的工作示例。 您需要提供Annotation对象的列表,这些对象描述需要突出显示哪些文本范围以及使用哪种样式。

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);
  }
}

此要点中也可用:https://gist.github.com/pulyaevskiy/d7af7217c2e71f31dfb78699f91dfbb5

答案 2 :(得分:0)

我认为还有更多“硬”方法可以做到这一点

第一个:

制作一个行小部件,添加String的一部分,直到要突出显示的单词,添加特殊单词,设置其样式,然后添加其余字符串。

或者,您可以尝试RichText

Günter发布了有关zefyr软件包的信息,我还没有使用过,但是如果适合您,我会很高兴为您提供帮助

答案 3 :(得分:0)

我实际上遇到了同样的问题,发现AnnotatedEditbleText对我有很大帮助。

我发布了有用的软件包来解决此类问题。

https://pub.dev/packages/hashtagable