跳到主内容

使用 Flutter 检查器

了解如何使用 Flutter 检查器来探索 Flutter 应用的 Widget 树。

有关如何在不同 IDE 中找到 DevTools 屏幕的信息,请查看 DevTools 概述

它是什么?

#

Flutter Widget 检查器是一个强大的工具,用于可视化和探索 Flutter Widget 树。Flutter 框架使用 Widget 作为构建任何内容的构建块,从控件(如文本、按钮和切换开关)到布局(如居中、填充、行和列)。该检查器可帮助您可视化和探索 Flutter Widget 树,并可用于以下目的

  • 理解现有的布局
  • 诊断布局问题

Screenshot of the Flutter inspector window

新的 Flutter 检查器

#

作为 Flutter 3.29 的一部分,新的 Flutter 检查器默认启用。但是,可以从 检查器设置对话框 中禁用它。

以视觉方式调试布局问题

#

以下是检查器工具栏中可用功能的指南。当空间有限时,图标将用作标签的视觉版本。

Select widget mode button
选择 Widget 模式

启用此按钮以选择设备上的 Widget 进行检查。要了解更多信息,请查看 检查一个 Widget

Show implementation widgets button
显示实现 Widget

启用此按钮以在 Widget 树中显示实现 Widget。要了解更多信息,请查看 使用 Widget 树

刷新树图标 刷新树

重新加载当前 Widget 信息。

缓慢的动画图标 缓慢的动画

以 5 倍的速度运行动画,以帮助微调它们。

显示引导线模式图标 显示引导线

覆盖引导线以帮助修复布局问题。

显示基线图标 显示基线

显示基线,用于对齐文本。对于检查文本是否对齐非常有用。

突出显示重绘图标 突出显示重绘

显示颜色会发生变化的边框,以显示元素重绘。对于查找不必要的重绘非常有用。

突出显示超大图像图标 突出显示超大图像

通过反转颜色和翻转来突出显示使用过多内存的图像。

检查一个 Widget

#

您可以浏览交互式 Widget 树以查看附近的 Widget 并查看它们的字段值。

要定位 Widget 树中的单个 UI 元素,请单击工具栏中的 选择 Widget 模式 按钮。这将使设备上的应用进入“Widget 选择”模式。单击应用 UI 中的任何 Widget;这将选择应用屏幕上的 Widget,并滚动到 Widget 树的相应节点。再次切换 选择 Widget 模式 按钮以退出 Widget 选择模式。

在调试布局问题时,关键字段是 sizeconstraints 字段。约束从树中向下流动,大小从树中向上流动。有关其工作原理的更多信息,请参阅 了解约束

Flutter Widget 树

#

Flutter Widget 树允许您可视化、理解和导航应用的 Widget 树。

Image of Flutter inspector with Widget Tree highlighted

使用 Widget 树

#

查看在您的项目中创建的 Widget

#

默认情况下,Flutter Widget 树包括在您的根项目目录中创建的所有 Widget。

Widget 的父子关系由单条垂直线表示(如果父 Widget 只有一个子 Widget),或者通过缩进表示(如果父 Widget 有多个子 Widget)。

例如,对于 Widget 树的以下部分

Image of widget tree section

  • Padding 具有单个子 Widget Row
  • Row 有三个子 Widget:IconSizedBoxFlexible
  • Flexible 具有单个子 Widget Column
  • Column 有四个子 Widget:TextTextSizedBoxDivider

查看所有 Widget

#

要改为查看 Widget 树中的所有 Widget,包括在您的项目外部创建的 Widget,请切换“显示实现 Widget”。

实现 Widget 以较浅的字体显示,从而在视觉上区分它们。它们也隐藏在可展开的组后面,可以通过内联展开按钮展开。

例如,以下是与实现 Widget 显示相同的 Widget 树部分

Image of widget tree section showing implementation widgets

  • Icon 具有五个折叠在其下方的实现 Widget
  • 两个 Text Widget 都有 RichText 实现 Widget 子 Widget
  • Divider 具有九个折叠在其下方的实现 Widget

Flutter Widget 资源管理器

#

Flutter Widget 资源管理器可帮助您更好地理解被检查的 Widget。

Image of Flutter inspector with Widget Explorer highlighted

使用 Widget 资源管理器

#

从 Flutter 检查器中,选择一个 Widget。Widget 资源管理器将显示在窗口的右侧。

根据所选 Widget,Widget 资源管理器将包括以下一个或多个选项卡

  • Widget 属性选项卡
  • Flex 资源管理器选项卡
  • Render 对象选项卡

Widget 属性选项卡

#

Image of widget properties tab

属性选项卡显示您的 Widget 布局的微型视图,包括宽度、高度和填充,以及该 Widget 上的属性列表。

这些属性包括该值是否与属性参数的默认值匹配。

Render 对象选项卡

#

Image of render object tab

Render 对象选项卡显示设置在所选 Flutter Widget 的 Render 对象上的所有属性。

Flex 资源管理器选项卡

#

Image of flex explorer tab

当您选择一个 Flex Widget(例如,RowColumnFlex)或 Flex Widget 的直接子 Widget 时,Flex 资源管理器工具将出现在 Widget 资源管理器中。

Flex 资源管理器工具可视化了 Flex Widget 及其子 Widget 的布局方式。资源管理器标识主轴和交叉轴,以及每个轴的当前对齐方式(例如,开始、结束和 spaceBetween)。它还显示诸如 flex 系数、flex 拟合和布局约束之类的详细信息。

此外,资源管理器显示布局约束违规和 Render 溢出错误。违反的布局约束以红色突出显示,溢出错误以标准的“黄色胶带”模式呈现,就像您在运行设备上看到的那样。这些可视化旨在帮助理解溢出错误发生的原因以及如何修复它们。

The flex explorer showing errors and device inspector

单击 Flex 资源管理器中的 Widget 会镜像设备上检查器中的选择。需要启用“选择 Widget 模式”才能实现这一点。要启用它,请单击检查器中的 选择 Widget 模式 按钮。

The Select Widget Mode button in the inspector

对于某些属性,例如 flex 系数、flex 拟合和对齐方式,您可以通过资源管理器中的下拉列表修改该值。修改 Widget 属性时,您不仅会在 flex 资源管理器中看到新值,还会看到在运行 Flutter 应用的设备上反映的新值。资源管理器会在属性更改时进行动画处理,以便清楚地了解更改的效果。从布局资源管理器进行的 Widget 属性更改不会修改您的源代码,并且会在热重载时还原。

交互式属性
#

Flex 资源管理器支持修改 mainAxisAlignmentcrossAxisAlignmentFlexParentData.flex。将来,我们可能会添加对其他属性的支持,例如 mainAxisSizetextDirectionFlexParentData.fit

mainAxisAlignment

The flex explorer changing main axis alignment

支持的值

  • MainAxisAlignment.start
  • MainAxisAlignment.end
  • MainAxisAlignment.center
  • MainAxisAlignment.spaceBetween
  • MainAxisAlignment.spaceAround
  • MainAxisAlignment.spaceEvenly
crossAxisAlignment

The flex explorer changing cross axis alignment

支持的值

  • CrossAxisAlignment.start
  • CrossAxisAlignment.center
  • CrossAxisAlignment.end
  • CrossAxisAlignment.stretch
FlexParentData.flex

The flex explorer changing flex factor

Flex 资源管理器在 UI 中支持 7 个 flex 选项(null、0、1、2、3、4、5),但从技术上讲,flex Widget 子 Widget 的 flex 系数可以是任何 int。

Flexible.fit

The flex explorer changing fit

Flex 资源管理器支持两种不同类型的 FlexFitloosetight

视觉调试

#

Flutter 检查器提供了几种用于以视觉方式调试应用的选项。

Inspector visual debugging options

缓慢的动画

#

启用后,此选项以 5 倍的速度运行动画,以便更轻松地进行视觉检查。如果您想仔细观察和调整看起来不太对劲的动画,这将非常有用。

这也可以在代码中设置

dart
import 'package:flutter/scheduler.dart';

void setSlowAnimations() {
  timeDilation = 5.0;
}

这会将动画速度降低 5 倍。

另请参阅

#

以下链接提供更多信息。

以下屏幕录像显示了减慢动画前后的情况。

Screen recording showing normal animation speed Screen recording showing slowed animation speed

显示引导线

#

此功能在您的应用上绘制引导线,显示 Render 框、对齐方式、填充、滚动视图、剪切和间隔。

此工具可用于更好地理解您的布局。例如,通过查找不需要的填充或了解 Widget 对齐方式。

您也可以在代码中启用它

dart
import 'package:flutter/rendering.dart';

void showLayoutGuidelines() {
  debugPaintSizeEnabled = true;
}

Render 框

#

绘制到屏幕上的 Widget 会创建一个 Render 框,这是 Flutter 布局的构建块。它们显示为亮蓝色边框

Screenshot of render box guidelines

对齐方式

#

对齐方式显示为黄色箭头。这些箭头显示 Widget 相对于其父 Widget 的垂直和水平偏移量。例如,此按钮的图标显示为由四个箭头居中

Screenshot of alignment guidelines

Padding

#

填充显示为半透明的蓝色背景

Screenshot of padding guidelines

滚动视图

#

具有滚动内容的 Widget(例如列表视图)显示为绿色箭头

Screenshot of scroll view guidelines

剪切

#

例如,在使用 ClipRect Widget 时,剪切显示为带有剪刀图标的虚线粉色线

Screenshot of clip guidelines

间隔

#

间隔 Widget 显示为灰色背景,例如此 SizedBox 没有子 Widget

Screenshot of spacer guidelines

显示基线

#

此选项使所有基线可见。基线是用于定位文本的水平线。

这对于检查文本是否精确垂直对齐非常有用。例如,以下屏幕截图中的文本基线略有错位

Screenshot with show baselines enabled

可以使用 Baseline Widget 调整基线。

在任何具有设置基线的 Render 框 上绘制一条线;字母基线显示为绿色,表意文字基线显示为黄色。

您也可以在代码中启用它

dart
import 'package:flutter/rendering.dart';

void showBaselines() {
  debugPaintBaselinesEnabled = true;
}

突出显示重绘

#

此选项会在所有 渲染框周围绘制边框,每次该框重绘时边框颜色都会改变。

这种旋转的彩虹色对于查找应用程序中重绘过于频繁的部分,以及可能损害性能的部分非常有用。

例如,一个小动画可能会导致整个页面在每一帧都重绘。将动画包装在 RepaintBoundary 组件中,可以将重绘限制在该动画内。

这里进度指示器导致其容器重绘

dart
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()),
    );
  }
}

Screen recording of a whole screen repainting

将进度指示器包装在 RepaintBoundary 中,只会导致屏幕的该部分重绘

dart
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()),
      ),
    );
  }
}

Screen recording of a just a progress indicator repainting

RepaintBoundary 组件具有权衡。它们可以帮助提高性能,但它们也具有创建新画布的开销,这会使用额外的内存。

您也可以在代码中启用此选项

dart
import 'package:flutter/rendering.dart';

void highlightRepaints() {
  debugRepaintRainbowEnabled = true;
}

突出显示超大图像

#

此选项通过反转颜色和垂直翻转来突出显示尺寸过大的图像

A highlighted oversized image

突出显示的图像使用的内存超过了实际需要的内存;例如,一个大型的 5MB 图像显示为 100 像素 x 100 像素。

这些图像可能导致性能下降,尤其是在低端设备上,并且当您有很多图像时(例如在列表视图中),性能下降会累积。有关每个图像的信息将在调试控制台中打印出来

dash.png has a display size of 213×392 but a decode size of 2130×392, which uses an additional 2542KB.

如果图像使用的内存比需要的内存多至少 128KB,则认为该图像尺寸过大。

修复图像

#

在可能的情况下,解决此问题的最佳方法是调整图像资源文件的大小,使其更小。

如果这不可行,您可以使用 Image 构造函数中的 cacheHeightcacheWidth 参数

dart
class ResizedImage extends StatelessWidget {
  const ResizedImage({super.key});

  @override
  Widget build(BuildContext context) {
    return Image.asset('dash.png', cacheHeight: 213, cacheWidth: 392);
  }
}

这将使引擎以指定的大小解码此图像,并减少内存使用量(解码和存储仍然比缩小图像资源本身更昂贵)。无论这些参数如何,图像都会渲染到布局或宽度和高度的约束范围内。

此属性也可以在代码中设置

dart
void showOversizedImages() {
  debugInvertOversizedImages = true;
}

更多信息

#

您可以在以下链接中了解更多信息

跟踪 Widget 创建

#

Flutter inspector 的一部分功能是基于对应用程序代码进行检测,以便更好地理解创建组件的源位置。源检测允许 Flutter inspector 以类似于您的源代码中定义 UI 的方式呈现组件树。如果没有它,组件树中的节点会更深,并且可能更难以理解运行时组件层次结构与应用程序 UI 的对应关系。

您可以通过将 --no-track-widget-creation 传递给 flutter run 命令来禁用此功能。

以下是启用和禁用跟踪组件创建时您的组件树可能看起来的示例。

启用跟踪组件创建(默认)

The widget tree with track widget creation enabled

禁用跟踪组件创建(不推荐)

The widget tree with track widget creation disabled

此功能可防止在调试构建中将否则相同的 const 组件视为相等。有关更多详细信息,请参阅 调试常见问题中的讨论。

检查器设置

#

The Flutter Inspector Settings dialog

启用悬停检查

#

将鼠标悬停在任何组件上都会显示其属性和值。

切换此值可启用或禁用悬停检查功能。

启用 Widget 树自动刷新

#

启用后,组件树将在热重载或导航事件后自动刷新。

使用旧版检查器

#

启用后,请使用 旧版 inspector 代替新的 inspector。

包目录

#

默认情况下,DevTools 将组件树中显示的组件限制为在项目根目录中创建的组件。要查看所有组件,包括在项目根目录之外创建的组件,请打开 显示实现组件

为了在默认组件树中包含其他组件,必须将它们的父目录添加到包目录。

例如,考虑以下目录结构

project_foo
  pkgs
    project_foo_app
    widgets_A
    widgets_B

project_foo_app 运行您的应用程序只会显示 project_foo/pkgs/project_foo_app 中的组件在组件 inspector 树中。

要在组件树中显示 widgets_A 中的组件,请将 project_foo/pkgs/widgets_A 添加到包目录。

要在组件树中显示项目根目录中的所有组件,请将 project_foo 添加到包目录。

对您的包目录所做的更改将在下次打开应用程序的组件 inspector 时保留。

其他资源

#

有关 inspector 可以实现的一般功能的演示,请参阅 2018 DartConf 演讲,演示了 IntelliJ 版本 Flutter inspector。

要了解如何使用 DevTools 视觉调试布局问题,请查看一个引导式的 Flutter Inspector 教程