Flutter自定义输入框同时出现多种字体颜色
- 效果展示
- 基本逻辑
- 代码示例
效果展示
输入框内效果
基本逻辑
主要通过重写TextEditingController中的buildTextSpan方法实现,通过在buildTextSpan中将内容手动切割(本人通过正则表达式将#这些话题分割开来),然后组装成为一个TextSpan 返回出去
buildTextSpan 是一个用于构建 TextSpan 对象的方法,它通常用于自定义文本样式或在 RichText 中构建富文本。
代码示例
class CustomTextEditingController extends TextEditingController {
//正则表达式切割文本内容
List<String> splitByHash(String input) {
RegExp regex = RegExp(r'#([a-zA-Z0-9\u4e00-\u9fa5\?]+)');
Iterable<Match> matches = regex.allMatches(input);
List<String> result = [];
int lastIndex = 0;
for (Match match in matches) {
String matchText = match.group(0)!;
int matchIndex = match.start;
// Add the text before the match
if (matchIndex > lastIndex) {
result.add(input.substring(lastIndex, matchIndex));
}
// Add the matched text
result.add(matchText);
lastIndex = matchIndex + matchText.length;
}
// Add the remaining text after the last match
if (lastIndex < input.length) {
result.add(input.substring(lastIndex));
}
return result;
}
TextSpan buildTextSpan({required BuildContext context, TextStyle? style, required bool withComposing}) {
List<AtModel> lis=[];
// 获取文本框中的文本
String value = text;
List<String> result = splitByHash(value);
//判断内容段中是否有想要变色的关键字符#,将内容封装到对象中,对象为自定义对象,id用不到所以默认值为1,body为内容段,isAt为是否变色
for(int i=0;i<result.length;i++){
if(result[i].isNotEmpty && result[i][0] == '#'){
AtModel at=new AtModel(id: "1", body: result[i], isAt: true);
lis.add(at);
}else{
AtModel at=new AtModel(id: "1", body: result[i], isAt: false);
lis.add(at);
}
}
// 创建一个默认样式
TextStyle defaultStyle = style ?? TextStyle();
//设置想要变颜色的TextSpan
TextSpan text_topic(String body){
return TextSpan(
text: '${body}',
style: TextStyle(
color: Colors.lightBlue, // 设置为蓝色
fontSize: 14,
fontWeight: FontWeight.bold,
),
);
}
TextSpan text_span(String body){
return TextSpan(
text: '${body}',
style: TextStyle(
// color: Colors.black,
fontSize: 14,
fontWeight: FontWeight.bold,
),
);
}
//组装组件
List<TextSpan> listText(){
List<TextSpan> list=[];
for(int i=0;i<lis.length;i++){
if(lis[i].isAt){
list.add(text_topic(lis[i].body));
}else{
list.add(text_span(lis[i].body));
}
}
return list;
}
// 创建一个富文本组件,设置不同的样式
return TextSpan(
style: defaultStyle,
children: listText(),
);
}
}
使用时直接使用即可
//旧版本
TextEditingController _content = TextEditingController();
//新版本
CustomTextEditingController _content = CustomTextEditingController();
TextField(
// autofocus: true,
maxLines: 15,
maxLength: 500,
controller: _content,
)