| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- import 'package:flutter/material.dart';
- class RichTextReplace extends StatelessWidget {
- final String text;
- final Map<String, String>? 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<InlineSpan> _buildTextSpans(
- String text, Map<String, String> replaceMap) {
- final List<InlineSpan> 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;
- }
- }
|