在TextField中实现复杂的样式
在Flutter开发中,如果想要用TextField实现复杂的样式,比如:
两个#之间被识别为tag,高亮为蓝色。
为了实现这样的效果,我们需要扩展TextEditingController:
import 'package:flutter/material.dart'; /* 保证输入框tag高亮的控制器 */ class CodeHighlightingController extends TextEditingController { /// 代码高亮 /// @param { String } text: 文字 List<TextSpan> codeHighlighting(BuildContext context, String text) { List<TextSpan> list = []; List<int> tagIndex = []; int textLength = text.length; // 获取"#"的index for (int i = 0; i < textLength; i++) { if (text[i] == '#') { tagIndex.add(tagIndex.length % 2 == 0 ? i : (i + 1)); } } // 奇数时删除数组最后一位,保证区间的完整 if (tagIndex.length % 2 != 0) { tagIndex.removeLast(); } if (tagIndex.length == 0) { // 没有tag,不需要处理 list.add(TextSpan(text: text, style: TextStyle(color: Colors.black))); } else { // 处理tag第一位 if (tagIndex[0] != 0) { list.add(TextSpan( text: text.substring(0, tagIndex[0]), style: TextStyle(color: Colors.black) )); } for (int i = 0; i < tagIndex.length; i++) { int startIndex = tagIndex[i]; int endIndex = i == (tagIndex.length - 1) ? textLength : tagIndex[i + 1]; if (startIndex != endIndex) { bool isLight = i % 2 == 0; String tagText = text.substring(startIndex, endIndex); if (tagText != '') { String componentText = text.substring(startIndex, endIndex); if (isLight) { list.add(TextSpan( text: componentText, style: TextStyle(color: Colors.blue) )); } else { list.add(TextSpan( text: componentText, style: TextStyle(color: Colors.black) )); } } } } } return list; } @override TextSpan buildTextSpan({ required BuildContext context, required bool withComposing, TextStyle? style }) { return TextSpan(children: codeHighlighting(context, text)); } }
之后用它来创建TextField的controller:
import 'package:flutter/material.dart'; import './code_highlighting_controller.dart'; final CodeHighlightingController _controller = CodeHighlightingController(); class Form extends StatelessWidget { @override Widget build(BuildContext context) { return TextField( controller: _controller, autofocus: true, minLines: 5, maxLines: null, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.newline, decoration: InputDecoration.collapsed(hintText: '请输入...'), ); } }