Flutter中如何为混合文本中的数字单独设置字体
Flutter 实现混合文本与数字的不同字体方案
方案1:利用RichText + 正则拆分内容
核心思路是通过正则表达式将混合的文本和数字拆分成独立片段,为每个片段设置对应字体样式后,用RichText组合展示。
- 定义匹配数字/非数字的正则规则:
final RegExp _textNumberRegex = RegExp(r'(\d+|\D+)');
- 编写拆分方法,将字符串拆分为片段列表:
List<String> splitTextAndNumbers(String input) { return _textNumberRegex.allMatches(input) .map((match) => match.group(0)!) .toList(); }
- 在UI中渲染:
RichText( text: TextSpan( children: splitTextAndNumbers("订单编号:20240521-001").map((segment) { final isNumber = RegExp(r'^\d+$').hasMatch(segment); return TextSpan( text: segment, style: TextStyle( fontFamily: isNumber ? 'NumberFont' : 'TextFont', fontSize: 16, color: Colors.black, ), ); }).toList(), ), )
方案2:封装自定义Widget复用逻辑
如果多处需要该效果,可封装成自定义Widget减少重复代码:
class MixedFontText extends StatelessWidget { final String text; final String textFont; final String numberFont; final TextStyle? baseStyle; const MixedFontText({ super.key, required this.text, required this.textFont, required this.numberFont, this.baseStyle, }); @override Widget build(BuildContext context) { final defaultStyle = baseStyle ?? const TextStyle(fontSize: 16, color: Colors.black); final segments = splitTextAndNumbers(text); return RichText( text: TextSpan( style: defaultStyle, children: segments.map((segment) { final isNumber = RegExp(r'^\d+$').hasMatch(segment); return TextSpan( text: segment, style: defaultStyle.copyWith( fontFamily: isNumber ? numberFont : textFont, ), ); }).toList(), ), ); } List<String> splitTextAndNumbers(String input) { final RegExp regex = RegExp(r'(\d+|\D+)'); return regex.allMatches(input).map((m) => m.group(0)!).toList(); } }
调用示例:
MixedFontText( text: "今日销售额:12345.67元", textFont: 'PingFangSC', numberFont: 'DINAlternate', baseStyle: const TextStyle(fontSize: 18), )
注意事项
- 确保自定义字体已在
pubspec.yaml中正确配置:
fonts: - family: TextFont fonts: - asset: assets/fonts/TextFont-Regular.ttf - family: NumberFont fonts: - asset: assets/fonts/NumberFont-Regular.ttf
- 正则规则可按需调整,比如支持带小数点、千分位的数字,只需修改匹配表达式即可。
内容的提问来源于stack exchange,提问作者KIRAx2000
相关产品推荐
相关产品推荐

