使用旧版 Flutter inspector
了解如何使用旧版 Flutter inspector 来浏览 Flutter 应用的 Widget 树。
旧版 Flutter inspector
#
可视化调试布局问题
#以下是 inspector 工具栏中可用功能的指南。当空间有限时,图标将作为标签的视觉版本使用。
-
选择 Widget 模式 -
启用此按钮以在设备上选择要检查的 Widget。要了解更多信息,请查看检查 Widget。
-
刷新树 重新加载当前的 Widget 信息。
-
慢速动画 将动画运行速度放慢 5 倍,以帮助微调动画。
-
显示辅助线 覆盖显示辅助线,以辅助修复布局问题。
-
显示基准线 -
显示用于对齐文本的基准线。这对于检查文本是否对齐非常有用。
-
高亮重绘 -
显示在元素重绘时会变色的边框。对于查找不必要的重绘非常有用。
-
高亮显示超大图片 -
通过反转颜色并翻转图片,来高亮显示那些占用过多内存的图片。
检查 Widget
#您可以浏览交互式 Widget 树,查看相邻的 Widget 并查看其字段值。
要在 Widget 树中定位特定的 UI 元素,请点击工具栏中的选择 Widget 模式按钮。这将使设备上的应用进入“Widget 选择”模式。点击应用 UI 中的任何 Widget;这会在应用屏幕上选中该 Widget,并将 Widget 树滚动到相应的节点。再次切换选择 Widget 模式按钮即可退出选择模式。
调试布局问题时,需要查看的关键字段是 size(大小)和 constraints(约束)。约束沿树向下流动,而大小则沿树向上回传。有关其工作原理的更多信息,请参阅理解约束。
Flutter 布局资源管理器 (Layout Explorer)
#Flutter 布局资源管理器 (Layout Explorer) 可帮助您更好地理解 Flutter 布局。
有关该工具功能的概述,请参阅 Flutter Explorer 视频
您可能还会发现以下分步指南很有用
使用布局资源管理器
#在 Flutter Inspector 中,选择一个 Widget。布局资源管理器支持弹性布局 (flex layouts) 和固定尺寸布局,并为两者提供了专门的工具。
弹性布局
#当您选择一个弹性 Widget(例如 Row、Column、Flex)或弹性 Widget 的直接子级时,布局资源管理器中会出现弹性布局工具。
布局资源管理器可视化了 Flex Widget 及其子级的布局方式。该资源管理器标识了主轴和交叉轴,以及每个轴的当前对齐方式(例如 start、end 和 spaceBetween)。它还显示了诸如弹性因子 (flex factor)、弹性适配 (flex fit) 和布局约束等详细信息。
此外,该资源管理器还显示布局约束冲突和渲染溢出错误。违反的布局约束以红色显示,溢出错误则以您在运行中的设备上可能看到的标准“黄条”模式呈现。这些可视化旨在提高对溢出错误发生原因以及如何修复它们的理解。
点击布局资源管理器中的 Widget 会镜像设备上 inspector 的选中状态。为此需要启用选择 Widget 模式。要启用它,请点击 inspector 中的选择 Widget 模式按钮。
对于某些属性,如弹性因子、弹性适配和对齐方式,您可以通过资源管理器中的下拉列表修改其值。修改 Widget 属性时,您不仅会在布局资源管理器中看到新值,还会看到在运行 Flutter 应用的设备上实时生效。资源管理器会对属性变更进行动画处理,使变更效果清晰可见。通过布局资源管理器所做的 Widget 属性变更不会修改您的源代码,并且在热重载后会还原。
交互式属性
#布局资源管理器支持修改 mainAxisAlignment、crossAxisAlignment 和 FlexParentData.flex。未来,我们可能会增加对其他属性的支持,例如 mainAxisSize、textDirection 和 FlexFit。
mainAxisAlignment
支持的值
MainAxisAlignment.startMainAxisAlignment.endMainAxisAlignment.centerMainAxisAlignment.spaceBetweenMainAxisAlignment.spaceAroundMainAxisAlignment.spaceEvenly
crossAxisAlignment
支持的值
CrossAxisAlignment.startCrossAxisAlignment.centerCrossAxisAlignment.endCrossAxisAlignment.stretch
FlexParentData.flex
布局资源管理器在 UI 中支持 7 个弹性选项 (null, 0, 1, 2, 3, 4, 5),但从技术上讲,弹性 Widget 子级的弹性因子可以是任何整数。
Flexible.fit
布局资源管理器支持两种类型的 FlexFit:loose 和 tight。
固定尺寸布局
#当您选择一个不是弹性 Widget 子级的固定尺寸 Widget 时,固定尺寸布局信息将出现在布局资源管理器中。您可以查看所选 Widget 及其最近上游 RenderObject 的大小、约束和内边距信息。
可视化调试
#Flutter Inspector 提供了多种选项来对您的应用进行可视化调试。
慢速动画
#启用此选项后,动画将以 5 倍慢速运行,以便于视觉检查。如果您想仔细观察和微调看起来不太对劲的动画,这非常有用。
这也可以在代码中设置
import 'package:flutter/scheduler.dart';
void setSlowAnimations() {
timeDilation = 5.0;
}
这会将动画速度降低至原来的 1/5。
另请参阅
#以下链接提供了更多信息。
以下屏幕录像展示了动画减速前后的对比。
显示辅助线
#此功能会在您的应用上绘制辅助线,显示渲染框、对齐方式、内边距、滚动视图、裁剪区域和间隔器。
此工具可用于更好地理解您的布局。例如,通过查找不需要的内边距或理解 Widget 的对齐方式。
您也可以在代码中启用它
import 'package:flutter/rendering.dart';
void showLayoutGuidelines() {
debugPaintSizeEnabled = true;
}
渲染框 (Render boxes)
#绘制到屏幕上的 Widget 会创建 渲染框,这是 Flutter 布局的构建块。它们以亮蓝色边框显示
对齐方式
#对齐方式用黄色箭头表示。这些箭头显示了 Widget 相对于其父级的垂直和水平偏移量。例如,该按钮的图标通过四个箭头显示为居中状态
Padding
#内边距以半透明蓝色背景显示
滚动视图
#带有滚动内容的 Widget(如列表视图)以绿色箭头显示
裁剪
#裁剪(例如使用 ClipRect Widget 时)以带有剪刀图标的虚线粉色线条显示
间隔器 (Spacers)
#间隔器 Widget 以灰色背景显示,例如这个没有子级的 SizedBox
显示基准线
#此选项使所有基准线可见。基准线是用于定位文本的水平线。
这对于检查文本是否在垂直方向上精确对齐非常有用。例如,在下方的截图中,文本基准线略有不对齐
Baseline Widget 可用于调整基准线。
任何设置了基准线的 渲染框 上都会画出一条线;字母基准线显示为绿色,表意文字基准线显示为黄色。
您也可以在代码中启用它
import 'package:flutter/rendering.dart';
void showBaselines() {
debugPaintBaselinesEnabled = true;
}
高亮重绘
#此选项在所有 渲染框 周围绘制边框,这些边框会在框每次重绘时改变颜色。
这种不断旋转的彩虹色对于发现应用中重绘过于频繁并可能损害性能的部分非常有用。
例如,一个小的动画可能会导致整个页面在每一帧都进行重绘。将动画包装在 RepaintBoundary Widget 中可以将重绘限制在仅该动画区域内。
在这里,进度指示器导致其容器重绘
class EverythingRepaintsPage extends StatelessWidget {
const EverythingRepaintsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Repaint Example')),
body: const Center(child: CircularProgressIndicator()),
);
}
}
将进度指示器包装在 RepaintBoundary 中会导致仅屏幕的该部分进行重绘
class AreaRepaintsPage extends StatelessWidget {
const AreaRepaintsPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Repaint Example')),
body: const Center(
child: RepaintBoundary(child: CircularProgressIndicator()),
),
);
}
}
RepaintBoundary Widget 是有权衡的。它们可以提高性能,但也会带来创建新画布的开销,这会消耗额外的内存。
您也可以在代码中启用此选项
import 'package:flutter/rendering.dart';
void highlightRepaints() {
debugRepaintRainbowEnabled = true;
}
高亮显示超大图片
#此选项通过反转图片颜色并垂直翻转图片,来高亮显示那些过大的图片
被高亮显示的图片占用了超出所需的内存;例如,一张 100x100 像素区域显示的 5MB 大图片。
此类图片可能导致性能不佳,特别是在低端设备上。当有许多此类图片时(例如在列表视图中),这种性能影响会累加。有关每张图片的信息会打印在调试控制台中
dash.png has a display size of 213×392 but a decode size of 2130×392, which uses an additional 2542KB.
如果图片占用的内存比所需的多出至少 128KB,则被认为过大。
修复图片
#尽可能地,解决此问题的最佳方法是调整图片资源文件的大小,使其更小。
如果无法做到,您可以使用 Image 构造函数中的 cacheHeight 和 cacheWidth 参数
class ResizedImage extends StatelessWidget {
const ResizedImage({super.key});
@override
Widget build(BuildContext context) {
return Image.asset('dash.png', cacheHeight: 213, cacheWidth: 392);
}
}
这使得引擎按指定的大小解码此图片,从而减少内存使用(解码和存储的开销仍然比缩小图片资源文件本身更大)。无论这些参数如何,图片都会按照布局的约束或指定的宽度和高度进行渲染。
此属性也可以在代码中设置
void showOversizedImages() {
debugInvertOversizedImages = true;
}
更多信息
#您可以通过以下链接了解更多信息
详情树
#选择 Widget 详情树标签以显示所选 Widget 的详情树。从这里,您可以收集有关 Widget 属性、渲染对象和子级的有用信息。
跟踪 Widget 创建
#Flutter inspector 的部分功能基于对应用程序代码进行插桩,以便更好地理解 Widget 的创建源位置。源代码插桩允许 Flutter inspector 以类似于您在源代码中定义 UI 的方式呈现 Widget 树。没有它,Widget 树中的节点层级会深得多,并且很难理解运行时的 Widget 层级如何与您的应用 UI 相对应。
您可以通过向 flutter run 命令传递 --no-track-widget-creation 参数来禁用此功能。
以下是启用和禁用“跟踪 Widget 创建”功能后,Widget 树可能呈现的示例。
启用跟踪 Widget 创建(默认)
禁用跟踪 Widget 创建(不推荐)
此功能阻止原本相同的 const Widget 在调试构建中被视为相等。有关更多详细信息,请参阅关于调试常见问题的讨论。
Inspector 设置
#
启用悬停检查
#悬停在任何 Widget 上都会显示其属性和值。
切换此值可以启用或禁用悬停检查功能。
包目录
#默认情况下,DevTools 将 Widget 树中显示的 Widget 限制为项目根目录和 Flutter SDK 中的 Widget。此过滤仅适用于 Inspector Widget 树(Inspector 左侧)中的 Widget,而不适用于 Widget 详情树(Inspector 右侧,与布局资源管理器在同一标签页视图中)。在 Widget 详情树中,您可以查看来自所有包的树中所有 Widget。
为了显示其他 Widget,必须将其父目录添加到“包目录”中。
例如,考虑以下目录结构
project_foo
pkgs
project_foo_app
widgets_A
widgets_B
从 project_foo_app 运行您的应用,仅在 Widget inspector 树中显示来自 project_foo/pkgs/project_foo_app 的 Widget。
要显示来自 widgets_A 的 Widget,请将 project_foo/pkgs/widgets_A 添加到包目录中。
要显示项目根目录中的所有 Widget,请将 project_foo 添加到包目录中。
您对包目录所做的更改在下次打开该应用的 Widget inspector 时会持久保存。
其他资源
#关于 inspector 的通用功能演示,请参阅 DartConf 2018 演讲,其中演示了 IntelliJ 版本的 Flutter inspector。
要了解如何使用 DevTools 对布局问题进行可视化调试,请查看引导式的 Flutter Inspector 教程。