如何以编程方式突出显示字符串中的单词

时间:2018-10-21 16:05:17

标签: dart flutter flutter-layout

是否可以更改字符串中特定单词的颜色?

Text("some long string")

现在我只想给个单词加颜色。

有人可以告诉我如何编程吗?

例如:-

  

我是一个很长很长的字符串,其中包含一些变量

现在在这里我想分开长词。 我可以将简单的字符串分开以突出显示一个单词,但不确定如何找到并突出显示每个单词。

10 个答案:

答案 0 :(得分:4)

将单词包装在TextSpan中并分配style属性以更改文本外观,并使用RichText代替Text

RichText(
  text: TextSpan(
    text: 'Hello ',
    style: DefaultTextStyle.of(context).style,
    children: <TextSpan>[
      TextSpan(text: 'bold', style: TextStyle(fontWeight: FontWeight.bold)),
      TextSpan(text: ' world!'),
    ],
  ),
)

或使用Text.rich构造函数https://docs.flutter.io/flutter/widgets/Text-class.html

const Text.rich(
  TextSpan(
    text: 'Hello', // default text style
    children: <TextSpan>[
      TextSpan(text: ' beautiful ', style: TextStyle(fontStyle: FontStyle.italic)),
      TextSpan(text: 'world', style: TextStyle(fontWeight: FontWeight.bold)),
    ],
  ),
)

答案 1 :(得分:1)

这是如何实现此目标的完整示例

使用useEffect(() => { console.log("current user changed", currentUser) },[currentUser]) 小部件的style属性将不同的样式应用于文本,并根据需要分配给它。

text

enter image description here

答案 2 :(得分:1)

Text.rich( 
  TextSpan(
    text: 'Some ', 
    children: <TextSpan>[
      TextSpan(
        text: ' Long ',
        style: TextStyle(fontWeight: FontWeight.bold , background: Paint()..color = Colors.red)),
      TextSpan(
        text: ' world',
        style: TextStyle(backgroundColor: Colors.yellow)),
              ],
            ),
          )

答案 3 :(得分:0)

这是我的代码。

class HighlightText extends StatelessWidget {
  final String text;
  final String highlight;
  final TextStyle style;
  final Color highlightColor;

  const HighlightText({
    Key key,
    this.text,
    this.highlight,
    this.style,
    this.highlightColor,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    String text = this.text ?? '';
    if ((highlight?.isEmpty ?? true) || text.isEmpty) {
      return Text(text, style: style);
    }

    List<TextSpan> spans = [];
    int start = 0;
    int indexOfHighlight;
    do {
      indexOfHighlight = text.indexOf(highlight, start);
      if (indexOfHighlight < 0) {
        // no highlight
        spans.add(_normalSpan(text.substring(start, text.length)));
        break;
      }
      if (indexOfHighlight == start) {
        // start with highlight.
        spans.add(_highlightSpan(highlight));
        start += highlight.length;
      } else {
        // normal + highlight
        spans.add(_normalSpan(text.substring(start, indexOfHighlight)));
        spans.add(_highlightSpan(highlight));
        start = indexOfHighlight + highlight.length;
      }
    } while (true);

    return Text.rich(TextSpan(children: spans));
  }

  TextSpan _highlightSpan(String content) {
    return TextSpan(text: content, style: style.copyWith(color: highlightColor));
  }

  TextSpan _normalSpan(String content) {
    return TextSpan(text: content, style: style);
  }
}

答案 4 :(得分:0)

您可以使用此flutter插件Highlight Text plugin。尝试是一个不错的选择

答案 5 :(得分:0)

我最近开发了一个名为“动态文本突出显示”的软件包。让您以编程方式突出显示给定文本中的某些给定单词。

看看https://pub.dev/packages/dynamic_text_highlighting

示例

Widget buildDTH(String text, List<String> highlights) {
  return DynamicTextHighlighting(
    text: text,
    highlights: highlights,
    color: Colors.yellow,
    style: TextStyle(
      fontSize: 18.0,
      fontStyle: FontStyle.italic,
    ),
    caseSensitive: false,
  );
}

这是一个无状态的小部件,因此对于任何更改,只需调用setState(() {...})

void applyChanges(List<String> newHighlights) {
  setState(() {
    highlights = newHighlights;
  });
}

答案 6 :(得分:0)

使用此代码甚至可以突出显示查询字母,请检查一次

arn:aws:s3:::mybucket/*

答案 7 :(得分:0)

zhpoo出色的answer上进行扩展,这是一个小部件代码段,可让您使用正则表达式(飞镖的RegExp)以编程方式设置样式/突出显示字符串中的任何内容

链接到dartpad演示:https://dartpad.dev/d7a0826ed1201f7247fafd9e65979953

class RegexTextHighlight extends StatelessWidget {
  final String text;
  final RegExp highlightRegex;
  final TextStyle highlightStyle;
  final TextStyle nonHighlightStyle;

  const RegexTextHighlight({
    @required this.text,
    @required this.highlightRegex,
    @required this.highlightStyle,
    this.nonHighlightStyle,
  });

  @override
  Widget build(BuildContext context) {
    if (text == null || text.isEmpty) {
      return Text("",
          style: nonHighlightStyle ?? DefaultTextStyle.of(context).style);
    }

    List<TextSpan> spans = [];
    int start = 0;
    while (true) {
      final String highlight =
          highlightRegex.stringMatch(text.substring(start));
      if (highlight == null) {
        // no highlight
        spans.add(_normalSpan(text.substring(start)));
        break;
      }

      final int indexOfHighlight = text.indexOf(highlight, start);

      if (indexOfHighlight == start) {
        // starts with highlight
        spans.add(_highlightSpan(highlight));
        start += highlight.length;
      } else {
        // normal + highlight
        spans.add(_normalSpan(text.substring(start, indexOfHighlight)));
        spans.add(_highlightSpan(highlight));
        start = indexOfHighlight + highlight.length;
      }
    }

    return RichText(
      text: TextSpan(
        style: nonHighlightStyle ?? DefaultTextStyle.of(context).style,
        children: spans,
      ),
    );
  }

  TextSpan _highlightSpan(String content) {
    return TextSpan(text: content, style: highlightStyle);
  }

  TextSpan _normalSpan(String content) {
    return TextSpan(text: content);
  }
}

答案 8 :(得分:0)

要实现这一点,有几种可能性:

1-使用 Text.rich 构造函数而不是 Text 小组件,然后在构造函数内部,您将使用TextSpan小组件允许您通过 style 属性添加样式。第一个TextSpan直接位于Text.rich中,然后另一个TextSpan通过其children属性位于第一个TextSpan中。

Text.rich( 
  TextSpan(
    text: 'Some ', 
    children: <TextSpan>[
      TextSpan(
        text: ' Long ',
        style: TextStyle(fontWeight: FontWeight.bold , background: Paint()..color = Colors.red)),
      TextSpan(
        text: ' world',
        style: TextStyle(backgroundColor: Colors.yellow)),
              ],
            ),
          )

输出:

enter image description here

2-使用RichText小部件。与Text.rich相同,但是这次将第一个TextSpan放在RichText小部件的 text 属性上。

RichText( 
  text:TextSpan(
     text: 'Some ', 
     style: TextStyle(color: Colors.blue), 
     children: <TextSpan>[
        TextSpan(
           text: ' Long ',
           style: TextStyle(color:Colors.black ,fontWeight: FontWeight.bold , background: Paint()..color = Colors.red)),
        TextSpan(
           text: ' world',
           style: TextStyle(backgroundColor: Colors.yellow)),
              ],
            ),
          )

输出:

enter image description here

3-使用外部包。 我建议您highlight_textsubstring_highlight

答案 9 :(得分:-2)

@Gauter Zochbauer是个好答案。如果要动态更改,请按照以下答案进行操作。

import 'package:flutter/material.dart';

void main() => runApp(new MaterialApp(
      title: 'Forms in Flutter',
      home: new LoginPage(),
    ));

class LoginPage extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => new _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {

  Color color =Colors.yellowAccent;

  @override
  Widget build(BuildContext context) {
    final Size screenSize = MediaQuery.of(context).size;

    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Login'),
      ),
      body: new Container(
          padding: new EdgeInsets.all(20.0),
          child: Column(
            children: <Widget>[
              Text.rich(
                TextSpan(
                  text: 'Hello', // default text style
                  children: <TextSpan>[
                    TextSpan(text: ' beautiful ', style: TextStyle(fontStyle: FontStyle.italic,color: color)),
                    TextSpan(text: 'world', style: TextStyle(fontWeight: FontWeight.bold)),
                  ],
                ),
              ),
              new RaisedButton(
                onPressed: (){
                  setState(() {
                    color == Colors.yellowAccent ? color = Colors.red : color = Colors.yellowAccent;
                  });
                },
              child: Text("Click Me!!!")
        ),
            ],
          )
    )); 
  }
}