使用 Flutter 检查器
它是什么?
#Flutter 窗口小部件检查器是一个强大的工具,用于可视化和探索 Flutter 窗口小部件树。Flutter 框架使用窗口小部件作为任何内容的核心构建块,从控件(例如文本、按钮和切换)到布局(例如居中、填充、行和列)。检查器可帮助您可视化和探索 Flutter 窗口小部件树,并可用于以下用途:
- 理解现有布局
- 诊断布局问题
开始
#要调试布局问题,请在调试模式下运行应用程序,然后单击 DevTools 工具栏上的Flutter 检查器选项卡打开检查器。
可视化调试布局问题
#以下是检查器工具栏中可用功能的指南。当空间有限时,图标用作标签的可视版本。
选择窗口小部件模式
- 启用此按钮以便选择设备上的窗口小部件以对其进行检查。要了解更多信息,请查看检查窗口小部件。
刷新树
- 重新加载当前窗口小部件信息。
慢动画
- 将动画速度降低 5 倍,以帮助微调动画。
显示指南
- 叠加指南以帮助修复布局问题。
显示基线
- 显示基线,用于对齐文本。可以用于检查文本是否对齐。
突出显示重绘
- 显示当元素重绘时颜色发生变化的边框。用于查找不必要的重绘。
突出显示超大图像
- 通过反转颜色并翻转图像来突出显示使用过多内存的图像。
检查窗口小部件
#您可以浏览交互式窗口小部件树以查看附近的窗口小部件并查看其字段值。
要查找窗口小部件树中的各个 UI 元素,请单击工具栏中的 选择窗口小部件模式 按钮。这会将设备上的应用程序置于“窗口小部件选择”模式。单击应用程序 UI 中的任何窗口小部件;这会选择应用程序屏幕上的窗口小部件,并将窗口小部件树滚动到相应的节点。再次切换 选择窗口小部件模式 按钮以退出窗口小部件选择模式。
调试布局问题时,要查看的关键字段是 size
和 constraints
字段。约束条件沿着树向下流动,大小沿着树向上流动。有关其工作原理的更多信息,请参阅理解约束。
Flutter 布局资源管理器
#Flutter 布局资源管理器可帮助您更好地理解 Flutter 布局。
有关您可以使用此工具执行的操作概述,请参阅 Flutter 资源管理器视频:
您可能还会发现以下分步文章很有用:
使用布局资源管理器
#在 Flutter 检查器中,选择一个窗口小部件。布局资源管理器支持弹性布局和固定大小布局,并且对这两种类型的布局都有特定的工具。
弹性布局
#当您选择一个弹性窗口小部件(例如,Row
、Column
、Flex
)或弹性窗口小部件的直接子窗口小部件时,弹性布局工具将出现在布局资源管理器中。
布局资源管理器可视化Flex
窗口小部件及其子窗口小部件的布局方式。资源管理器标识主轴和交叉轴,以及每个轴的当前对齐方式(例如,开始、结束和 spaceBetween)。它还显示弹性因子、弹性适应和布局约束等详细信息。
此外,资源管理器还显示布局约束冲突和渲染溢出错误。冲突的布局约束以红色显示,溢出错误以标准的“黄色胶带”模式显示,就像您在运行的设备上看到的那样。这些可视化旨在提高对溢出错误发生原因以及如何修复它们的理解。
单击布局资源管理器中的窗口小部件会镜像设备检查器上的选择。为此需要启用 选择窗口小部件模式 。要启用它,请单击检查器中的 选择窗口小部件模式 按钮。
对于某些属性(如弹性因子、弹性适应和对齐方式),您可以通过资源管理器中的下拉列表修改值。修改窗口小部件属性时,您不仅可以在布局资源管理器中看到新的值,还可以在运行 Flutter 应用程序的设备上看到新的值。资源管理器在属性更改时会进行动画处理,以便更改的效果清晰可见。从布局资源管理器进行的窗口小部件属性更改不会修改您的源代码,并在热重载时恢复。
交互式属性
#布局资源管理器支持修改mainAxisAlignment
、crossAxisAlignment
和FlexParentData.flex
。将来,我们可能会添加对其他属性的支持,例如mainAxisSize
、textDirection
和FlexParentData.fit
。
mainAxisAlignment
#支持的值:
MainAxisAlignment.start
MainAxisAlignment.end
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceAround
MainAxisAlignment.spaceEvenly
crossAxisAlignment
#支持的值:
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.end
CrossAxisAlignment.stretch
FlexParentData.flex
#布局资源管理器在 UI 中支持 7 个弹性选项(null、0、1、2、3、4、5),但从技术上讲,弹性窗口小部件子窗口小部件的弹性因子可以是任何整数。
Flexible.fit
#布局资源管理器支持两种不同类型的FlexFit
:loose
和 tight
。
固定大小布局
#当您选择不是弹性窗口小部件子窗口小部件的固定大小窗口小部件时,固定大小布局信息将出现在布局资源管理器中。您可以查看所选窗口小部件及其最近的上游 RenderObject 的大小、约束和填充信息。
可视化调试
#Flutter 检查器提供了几种可视化调试应用程序的选项。
慢动画
#启用此选项后,此选项会将动画速度降低 5 倍,以便于视觉检查。如果您想仔细观察和调整看起来不太合适的动画,这将非常有用。
这也可以在代码中设置:
import 'package:flutter/scheduler.dart';
void setSlowAnimations() {
timeDilation = 5.0;
}
这会将动画速度降低 5 倍。
另请参阅
#以下链接提供更多信息。
以下屏幕录制显示动画速度降低前后的情况。
显示指南
#此功能会在您的应用程序上绘制指南,以显示渲染框、对齐方式、填充、滚动视图、剪辑和间隔符。
此工具可用于更好地理解您的布局。例如,通过查找不需要的填充或理解窗口小部件对齐方式。
您也可以在代码中启用此功能:
import 'package:flutter/rendering.dart';
void showLayoutGuidelines() {
debugPaintSizeEnabled = true;
}
渲染框
#绘制到屏幕的窗口小部件会创建一个渲染框,它是 Flutter 布局的构建块。它们以亮蓝色边框显示:
对齐方式
#对齐方式以黄色箭头显示。这些箭头显示窗口小部件相对于其父级的垂直和水平偏移量。例如,此按钮的图标显示为由四个箭头居中:
填充
#填充以半透明蓝色背景显示:
滚动视图
#具有滚动内容的窗口小部件(例如列表视图)以绿色箭头显示:
剪辑
#剪辑,例如使用ClipRect 窗口小部件时,以带有剪刀图标的虚线粉色线显示:
间隔符
#间隔符窗口小部件以灰色背景显示,
例如,这个没有子元素的 SizedBox
:
显示基线
#此选项使所有基线可见。基线是用于定位文本的水平线。
这对于检查文本是否垂直精确对齐很有用。例如,以下屏幕截图中的文本基线略微错位:
可以使用Baseline 窗口小部件来调整基线。
在任何设置了基线的渲染框上都会绘制一条线;字母基线显示为绿色,表意基线显示为黄色。
您也可以在代码中启用此功能:
import 'package:flutter/rendering.dart';
void showBaselines() {
debugPaintBaselinesEnabled = true;
}
突出显示重绘
#此选项会在每次重绘该框时颜色都会改变的所有渲染框周围绘制边框。
这种旋转的彩虹色对于查找应用程序中重绘过于频繁且可能损害性能的部分很有用。
例如,一个小的动画可能会导致整个页面在每一帧都重绘。将动画包装在RepaintBoundary 窗口小部件中会将重绘限制在动画本身。
此处进度指示器会导致其容器重绘:
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
窗口小部件存在权衡。它们可以帮助提高性能,但它们还会增加创建新画布的开销,从而使用更多内存。
您也可以在代码中启用此选项:
import 'package:flutter/rendering.dart';
void highlightRepaints() {
debugRepaintRainbowEnabled = true;
}
突出显示超大图像
#此选项通过反转图像颜色并垂直翻转图像来突出显示过大的图像:
突出显示的图像使用的内存比所需的内存更多;例如,在 100x100 像素处显示的大型 5MB 图像。
此类图像可能会导致性能下降,尤其是在低端设备上以及当您有很多图像时(例如在列表视图中),这种性能下降会累积起来。有关每个图像的信息将打印在调试控制台中:
dash.png 的显示大小为 213×392,但解码大小为 2130×392,这额外使用了 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;
}
更多信息
#您可以在以下链接中了解更多信息:
详情树
#选择 窗口小部件详细信息树 选项卡以显示所选窗口小部件的详细信息树。在这里,您可以收集有关窗口小部件的属性、渲染对象和子项的有用信息。
跟踪窗口小部件创建
#Flutter 检查器部分功能基于检测应用程序代码,以便更好地理解创建窗口小部件的源位置。源检测允许 Flutter 检查器以类似于在源代码中定义 UI 的方式呈现窗口小部件树。如果没有它,窗口小部件树中的节点树会更深,并且可能更难以理解运行时窗口小部件层次结构如何与应用程序的 UI 相对应。
您可以通过将 --no-track-widget-creation
传递给 flutter run
命令来禁用此功能。
以下是启用和禁用窗口小部件创建跟踪时窗口小部件树可能是什么样子的示例。
启用窗口小部件创建跟踪(默认):
禁用窗口小部件创建跟踪(不推荐):
此功能可防止在调试版本中将其他完全相同的 const
窗口小部件视为相等。有关详细信息,请参阅有关调试时的常见问题的讨论。
检查器设置
#启用悬停检查
#将鼠标悬停在任何窗口小部件上都会显示其属性和值。
切换此值可启用或禁用悬停检查功能。
包目录
#默认情况下,DevTools 将窗口小部件树中显示的窗口小部件限制为项目根目录和 Flutter 中的窗口小部件。此筛选仅适用于检查器窗口小部件树(检查器的左侧)中的窗口小部件,而不适用于窗口小部件详细信息树(检查器中与布局资源管理器位于同一选项卡视图的右侧)。在窗口小部件详细信息树中,您可以看到树中来自所有包的所有窗口小部件。
要显示其他窗口小部件,必须将其父目录添加到包目录中。
例如,考虑以下目录结构:
project_foo
pkgs
project_foo_app
widgets_A
widgets_B
从 project_foo_app
运行您的应用程序会在窗口小部件检查器树中仅显示来自 project_foo/pkgs/project_foo_app
的窗口小部件。
要显示窗口小部件树中来自 widgets_A
的窗口小部件,请将 project_foo/pkgs/widgets_A
添加到包目录中。
要显示窗口小部件树中项目根目录中的 所有 窗口小部件,请将 project_foo
添加到包目录中。
下次为应用程序打开窗口小部件检查器时,对包目录的更改将保留。
其他资源
#有关检查器通常可能实现的功能的演示,请参阅DartConf 2018 演讲,该演讲演示了 IntelliJ 版本的 Flutter 检查器。
要了解如何使用 DevTools 可视化调试布局问题,请查看指导性的Flutter 检查器教程。
除非另有说明,否则本网站上的文档反映的是 Flutter 的最新稳定版本。页面最后更新于 2025-01-30。 查看源代码 或 报告问题。