Flutter自定义输入框同时出现多种字体颜色

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,
)

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值