import 'package:flutter/material.dart'; class RichTextReplace extends StatelessWidget { final String text; final Map? items; final TextStyle? defaultStyle; final TextStyle? replacedStyle; const RichTextReplace({ super.key, required this.text, this.items, this.defaultStyle, this.replacedStyle, }); @override Widget build(BuildContext context) { final spans = _buildTextSpans( text, items ?? {}, // 如果为空,传空 map ); return RichText( text: TextSpan( children: spans, style: defaultStyle ?? DefaultTextStyle.of(context).style, ), ); } List _buildTextSpans( String text, Map replaceMap) { final List spans = []; int currentIndex = 0; final regex = RegExp(r'\$\{(.*?)\}'); for (final match in regex.allMatches(text)) { final fullKey = match.group(0)!; // e.g. ${unlockCount} final key = match.group(1)!; // e.g. unlockCount // 普通文本部分 if (match.start > currentIndex) { spans.add(TextSpan(text: text.substring(currentIndex, match.start))); } // 替换值(优先使用 ${key} 匹配,兼容性更好) final replaced = replaceMap[fullKey] ?? replaceMap[key] ?? ''; // 加粗或自定义样式的替换值 spans.add(TextSpan( text: replaced, style: replacedStyle ?? const TextStyle(fontWeight: FontWeight.bold), )); currentIndex = match.end; } // 尾部普通文本 if (currentIndex < text.length) { spans.add(TextSpan(text: text.substring(currentIndex))); } return spans; } }