Flutter应用中如何在所有文本旁展示对应Font Size与Weight用于测试
Flutter 全应用文本字号字重调试展示方案
以下两种方案均仅在调试模式下生效,不会侵入生产环境代码。
方案1:全局无侵入拦截(无需修改现有业务代码)
利用MaterialApp/CupertinoApp的builder参数全局拦截Widget树,自动识别所有Text组件并附加字号字重信息,支持覆盖第三方库内的文本。
实现代码
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: '业务应用', theme: ThemeData(primarySwatch: Colors.blue), home: const HomePage(), // 全局拦截入口 builder: (context, child) { // 仅调试模式开启 if (!kDebugMode) return child!; return _DebugTextWrapper(child: child!); }, ); } } class _DebugTextWrapper extends StatelessWidget { final Widget child; const _DebugTextWrapper({required this.child}); @override Widget build(BuildContext context) => _traverseWidgetTree(child); Widget _traverseWidgetTree(Widget widget) { // 识别Text组件,附加信息 if (widget is Text) { final defaultStyle = DefaultTextStyle.of(context).style; final targetStyle = widget.style ?? defaultStyle; final fontSize = targetStyle.fontSize?.toStringAsFixed(1) ?? 'default'; final fontWeight = targetStyle.fontWeight?.toString().split('.').last ?? 'default'; // 两种展示方式二选一: // 方式1:Tooltip不破坏原有布局,PC端hover、移动端长按查看 return Tooltip( message: '字号: $fontSize | 字重: $fontWeight', triggerMode: TooltipTriggerMode.longPress, child: widget, ); // 方式2:直接在文本下方标注,直观展示但会影响原有布局 // return Column( // mainAxisSize: MainAxisSize.min, // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // widget, // Text( // '[$fontSize | $fontWeight]', // style: const TextStyle(fontSize: 8, color: Colors.redAccent), // ) // ], // ); } // 递归处理多子组件容器 if (widget is MultiChildRenderObjectWidget) { return (widget.runtimeType as dynamic)( key: widget.key, children: widget.children.map(_traverseWidgetTree).toList(), ) as Widget; } // 递归处理单子组件容器 if (widget is SingleChildRenderObjectWidget) { return (widget.runtimeType as dynamic)( key: widget.key, child: widget.child == null ? null : _traverseWidgetTree(widget.child!), ) as Widget; } // 其他组件直接返回 return widget; } }
方案优势
- 零业务代码侵入,引入后直接生效
- 覆盖范围完整,包括第三方依赖库内的Text组件
方案2:自定义全局Text组件(灵活控制展示粒度)
如果团队已统一使用封装的全局Text组件,直接在组件内添加调试逻辑即可,性能更优。
实现代码
import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; class CustomText extends StatelessWidget { final String text; final TextStyle? style; // 其余Text的属性按需透传 const CustomText(this.text, {super.key, this.style}); @override Widget build(BuildContext context) { if (!kDebugMode) { return Text(text, style: style); } final defaultStyle = DefaultTextStyle.of(context).style; final targetStyle = style ?? defaultStyle; final fontSize = targetStyle.fontSize?.toStringAsFixed(1) ?? 'default'; final fontWeight = targetStyle.fontWeight?.toString().split('.').last ?? 'default'; return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(text, style: style), Text( '[$fontSize | $fontWeight]', style: const TextStyle(fontSize: 8, color: Colors.redAccent), ) ], ); } }
方案优势
- 性能更高,无需递归遍历整棵Widget树
- 控制粒度灵活,可针对特定页面、特定文本单独开关展示逻辑
注意事项
- 若选择直接标注的展示方式,建议测试完成后切换回Tooltip模式,避免影响UI还原度验证
- 两种方案的调试逻辑在生产打包时会被自动摇树优化,不会增加生产包体积
内容的提问来源于stack exchange,提问作者Raja
相关产品推荐
相关产品推荐

