如何以编程方式在 flutter 中突出显示字符串中的单词
How to highlight a word in string in flutter programmatically
有什么方法可以改变字符串中特定单词的颜色吗?
Text("some long string")
现在我只想给长字上色。
谁能告诉我如何以编程方式执行此操作?
例如:-
I am long a really long and long string in some variable, a long one
现在我想把长单词分开。
我可以分离简单的字符串来突出显示一个词,但不确定如何找到并突出显示这些词中的每一个。
将单词换成 TextSpan and assign style
properties to change the text appearance and use 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)),
],
),
)
这是@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!!!")
),
],
)
));
}
}
这是我的代码。
import 'package:flutter/material.dart';
class HighlightText extends StatelessWidget {
final String text;
final String highlight;
final TextStyle style;
final TextStyle highlightStyle;
final Color highlightColor;
final bool ignoreCase;
HighlightText({
Key key,
this.text,
this.highlight,
this.style,
this.highlightColor,
TextStyle highlightStyle,
this.ignoreCase: false,
}) : assert(
highlightColor == null || highlightStyle == null,
'highlightColor and highlightStyle cannot be provided at same time.',
),
highlightStyle = highlightStyle ?? style?.copyWith(color: highlightColor) ?? TextStyle(color: highlightColor),
super(key: key);
@override
Widget build(BuildContext context) {
final text = this.text ?? '';
if ((highlight?.isEmpty ?? true) || text.isEmpty) {
return Text(text, style: style);
}
var sourceText = ignoreCase ? text.toLowerCase() : text;
var targetHighlight = ignoreCase ? highlight.toLowerCase() : highlight;
List<TextSpan> spans = [];
int start = 0;
int indexOfHighlight;
do {
indexOfHighlight = sourceText.indexOf(targetHighlight, start);
if (indexOfHighlight < 0) {
// no highlight
spans.add(_normalSpan(text.substring(start)));
break;
}
if (indexOfHighlight > start) {
// normal text before highlight
spans.add(_normalSpan(text.substring(start, indexOfHighlight)));
}
start = indexOfHighlight + highlight.length;
spans.add(_highlightSpan(text.substring(indexOfHighlight, start)));
} while (true);
return Text.rich(TextSpan(children: spans));
}
TextSpan _highlightSpan(String content) {
return TextSpan(text: content, style: highlightStyle);
}
TextSpan _normalSpan(String content) {
return TextSpan(text: content, style: style);
}
}
你可以使用这个 flutter 插件 Highlight Text plugin。试试
是个不错的选择
我最近开发了一个名为 Dynamic Text Highlighting 的软件包。它可以让您以编程方式突出显示给定文本中的某些给定单词。
看看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;
});
}
这是一个完整的示例,说明如何实现此目的
使用 text
的 style
属性 将不同的 样式 应用于 文本 小部件并将其分配给您的需要。
RichText(
textAlign: TextAlign.center,
text: TextSpan(children: <TextSpan>[
TextSpan(
text: getTranslated(context, "We will send"),
style: TextStyle(color: Colors.black87)),
TextSpan(
text: "One Time Password",
style: TextStyle( color: Colors.blue,
fontWeight: FontWeight.bold)),
TextSpan(
text: "to your mobile number or email id",
style: TextStyle(color: Colors.black87)),
]),
)
使用此代码它甚至会突出显示查询字母,检查一次
List<TextSpan> highlight(
String main, String query) {
List<TextSpan> children = [];
List<String> abc = query.toLowerCase().split("");
for (int i = 0; i < main.length; i++) {
if (abc.contains(main[i])) {
children.add(TextSpan(
text: main[i],
style: TextStyle(
backgroundColor: Colors.yellow[300],
color: Colors.black,
decoration: TextDecoration.none,
fontFamily: fontName,
fontWeight: FontWeight.bold,
fontSize: 16)));
} else {
children.add(TextSpan(
text: main[i],
style: TextStyle(
color: Colors.black,
decoration: TextDecoration.none,
fontFamily: fontName,
fontWeight: FontWeight.w300,
fontSize: 16)));
}
}
return children;
}
在 zhpoo's awesome 上进行扩展,这是一个小部件片段,它允许您使用 正则表达式 (dart 的 RegExp)以编程方式 style/highlight 字符串中的任何内容。
Link 到 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);
}
}
要实现这一点,有几种可能性:
1- 使用 Text.rich constructor instead of the Text widget and then inside the constructor, you will use the TextSpan 小部件,您可以通过 style 属性 添加样式。第一个 TextSpan 直接在 Text.rich 中,然后另一个 TextSpan 通过它的子 属性.
在第一个 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)),
],
),
)
输出:
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)),
],
),
)
输出:
3-外部包的使用。
我向你求婚highlight_text or substring_highlight
有什么方法可以改变字符串中特定单词的颜色吗?
Text("some long string")
现在我只想给长字上色。
谁能告诉我如何以编程方式执行此操作?
例如:-
I am long a really long and long string in some variable, a long one
现在我想把长单词分开。 我可以分离简单的字符串来突出显示一个词,但不确定如何找到并突出显示这些词中的每一个。
将单词换成 TextSpan and assign style
properties to change the text appearance and use 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)), ], ), )
这是@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!!!")
),
],
)
));
}
}
这是我的代码。
import 'package:flutter/material.dart';
class HighlightText extends StatelessWidget {
final String text;
final String highlight;
final TextStyle style;
final TextStyle highlightStyle;
final Color highlightColor;
final bool ignoreCase;
HighlightText({
Key key,
this.text,
this.highlight,
this.style,
this.highlightColor,
TextStyle highlightStyle,
this.ignoreCase: false,
}) : assert(
highlightColor == null || highlightStyle == null,
'highlightColor and highlightStyle cannot be provided at same time.',
),
highlightStyle = highlightStyle ?? style?.copyWith(color: highlightColor) ?? TextStyle(color: highlightColor),
super(key: key);
@override
Widget build(BuildContext context) {
final text = this.text ?? '';
if ((highlight?.isEmpty ?? true) || text.isEmpty) {
return Text(text, style: style);
}
var sourceText = ignoreCase ? text.toLowerCase() : text;
var targetHighlight = ignoreCase ? highlight.toLowerCase() : highlight;
List<TextSpan> spans = [];
int start = 0;
int indexOfHighlight;
do {
indexOfHighlight = sourceText.indexOf(targetHighlight, start);
if (indexOfHighlight < 0) {
// no highlight
spans.add(_normalSpan(text.substring(start)));
break;
}
if (indexOfHighlight > start) {
// normal text before highlight
spans.add(_normalSpan(text.substring(start, indexOfHighlight)));
}
start = indexOfHighlight + highlight.length;
spans.add(_highlightSpan(text.substring(indexOfHighlight, start)));
} while (true);
return Text.rich(TextSpan(children: spans));
}
TextSpan _highlightSpan(String content) {
return TextSpan(text: content, style: highlightStyle);
}
TextSpan _normalSpan(String content) {
return TextSpan(text: content, style: style);
}
}
你可以使用这个 flutter 插件 Highlight Text plugin。试试
是个不错的选择我最近开发了一个名为 Dynamic Text Highlighting 的软件包。它可以让您以编程方式突出显示给定文本中的某些给定单词。
看看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;
});
}
这是一个完整的示例,说明如何实现此目的
使用 text
的 style
属性 将不同的 样式 应用于 文本 小部件并将其分配给您的需要。
RichText(
textAlign: TextAlign.center,
text: TextSpan(children: <TextSpan>[
TextSpan(
text: getTranslated(context, "We will send"),
style: TextStyle(color: Colors.black87)),
TextSpan(
text: "One Time Password",
style: TextStyle( color: Colors.blue,
fontWeight: FontWeight.bold)),
TextSpan(
text: "to your mobile number or email id",
style: TextStyle(color: Colors.black87)),
]),
)
使用此代码它甚至会突出显示查询字母,检查一次
List<TextSpan> highlight(
String main, String query) {
List<TextSpan> children = [];
List<String> abc = query.toLowerCase().split("");
for (int i = 0; i < main.length; i++) {
if (abc.contains(main[i])) {
children.add(TextSpan(
text: main[i],
style: TextStyle(
backgroundColor: Colors.yellow[300],
color: Colors.black,
decoration: TextDecoration.none,
fontFamily: fontName,
fontWeight: FontWeight.bold,
fontSize: 16)));
} else {
children.add(TextSpan(
text: main[i],
style: TextStyle(
color: Colors.black,
decoration: TextDecoration.none,
fontFamily: fontName,
fontWeight: FontWeight.w300,
fontSize: 16)));
}
}
return children;
}
在 zhpoo's awesome
Link 到 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);
}
}
要实现这一点,有几种可能性:
1- 使用 Text.rich constructor instead of the Text widget and then inside the constructor, you will use the TextSpan 小部件,您可以通过 style 属性 添加样式。第一个 TextSpan 直接在 Text.rich 中,然后另一个 TextSpan 通过它的子 属性.
在第一个 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)),
],
),
)
输出:
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)),
],
),
)
输出:
3-外部包的使用。 我向你求婚highlight_text or substring_highlight