跳至主要内容

使用 Flutter 检查器

它是什么?

#

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

  • 了解现有布局
  • 诊断布局问题

Screenshot of the Flutter inspector window

入门

#

要调试布局问题,请在 调试模式 下运行应用程序,然后通过点击 DevTools 工具栏上的**Flutter 检查器**选项卡打开检查器。

可视化调试布局问题

#

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

选择小部件模式图标 选择小部件模式
启用此按钮以选择设备上的小部件以进行检查。要了解更多信息,请查看 检查小部件
刷新树图标 刷新树
重新加载当前的小部件信息。
缓慢动画图标 缓慢动画
将动画速度降低 5 倍,以帮助微调它们。
显示指南模式图标 显示指南
覆盖指南以帮助解决布局问题。
显示基线图标 显示基线
显示基线,用于对齐文本。可以用于检查文本是否对齐。
突出显示重绘图标 突出显示重绘
显示颜色变化的边框,当元素重绘时。有助于查找不必要的重绘。
突出显示超大图像图标 突出显示超大图像
通过反转颜色和翻转来突出显示使用过多内存的图像。

检查小部件

#

您可以浏览交互式小部件树以查看附近的小部件并查看其字段值。

要在小部件树中定位单个 UI 元素,请点击工具栏中的**选择小部件模式**按钮。这会将设备上的应用程序置于“小部件选择”模式。点击应用程序 UI 中的任何小部件;这将在应用程序屏幕上选择小部件,并将小部件树滚动到相应节点。再次切换**选择小部件模式**按钮以退出小部件选择模式。

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

Flutter 布局资源管理器

#

Flutter 布局资源管理器可以帮助您更好地理解 Flutter 布局。

有关您可以使用此工具执行的操作概述,请观看 Flutter 资源管理器视频


DevTools 布局资源管理器

您可能还会发现以下分步文章很有用

使用布局资源管理器

#

从 Flutter 检查器中,选择一个小部件。布局资源管理器同时支持 弹性布局 和固定大小布局,并且针对这两种布局都提供了特定的工具。

弹性布局

#

当您选择一个弹性小部件(例如,RowColumnFlex)或弹性小部件的直接子项时,弹性布局工具将出现在布局资源管理器中。

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

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

The Layout Explorer showing errors and device inspector

点击布局资源管理器中的一个小部件会镜像设备上检查器中的选择。为此需要启用**选择小部件模式**。要启用它,请点击检查器中的**选择小部件模式**按钮。

The Select Widget Mode button in the inspector

对于某些属性,例如弹性因子、弹性拟合和对齐方式,您可以通过资源管理器中的下拉列表修改其值。修改小部件属性时,您不仅可以在布局资源管理器中看到新的值,还可以在运行 Flutter 应用程序的设备上看到。资源管理器在属性更改时会进行动画处理,以便更改的效果清晰可见。从布局资源管理器进行的小部件属性更改不会修改您的源代码,并且在热重载时会恢复。

交互式属性
#

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

mainAxisAlignment
#

The Layout Explorer changing main axis alignment

支持的值

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

The Layout Explorer changing cross axis alignment

支持的值

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

The Layout Explorer changing flex factor

布局资源管理器在 UI 中支持 7 个弹性选项(null、0、1、2、3、4、5),但在技术上,弹性小部件子项的弹性因子可以是任何整数。

Flexible.fit
#

The Layout Explorer changing fit

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

固定大小布局

#

当您选择一个不是弹性小部件子项的固定大小小部件时,固定大小布局信息将出现在布局资源管理器中。您可以查看所选小部件及其最近的上游 RenderObject 的大小、约束和填充信息。

The Layout Explorer fixed size tool

视觉调试

#

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

显示指南

#

此功能会在您的应用程序上绘制指南,显示渲染框、对齐方式、填充、滚动视图、裁剪和间隔符。

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

您也可以在代码中启用此功能

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

void showLayoutGuidelines() {
  debugPaintSizeEnabled = true;
}

渲染框

#

绘制到屏幕上的小部件会创建一个 渲染框,它是 Flutter 布局的构建块。它们以亮蓝色的边框显示

Screenshot of render box guidelines

对齐方式

#

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

Screenshot of alignment guidelines

填充

#

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

Screenshot of padding guidelines

滚动视图

#

具有滚动内容的小部件(例如列表视图)以绿色箭头显示

Screenshot of scroll view guidelines

裁剪

#

裁剪,例如使用 ClipRect 小部件 时,以虚线粉红色线条和剪刀图标显示

Screenshot of clip guidelines

间隔符

#

间隔符小部件以灰色背景显示,例如此没有子项的SizedBox

Screenshot of spacer guidelines

显示基线

#

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

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

Screenshot with show baselines enabled

Baseline 小部件可用于调整基线。

在任何设置了基线的 渲染框 上都会绘制一条线;字母基线显示为绿色,表意基线显示为黄色。

您也可以在代码中启用此功能

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

突出显示的图像使用的内存超过了所需内存;例如,以 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构造函数上使用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 详情树**选项卡以显示所选 Widget 的详情树。在这里,您可以收集有关 Widget 属性、渲染对象和子元素的有用信息。

The Details Tree view

跟踪小部件创建

#

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

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

以下是启用和禁用跟踪 Widget 创建时 Widget 树可能是什么样子的示例。

启用跟踪 Widget 创建(默认)

The widget tree with track widget creation enabled

禁用跟踪 Widget 创建(不推荐)

The widget tree with track widget creation disabled

此功能阻止在调试版本中将其他情况下相同的const Widget 视为相等。有关更多详细信息,请参阅关于调试时常见问题的讨论。

检查器设置

#

The Flutter Inspector Settings dialog

启用悬停检查

#

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

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

包目录

#

默认情况下,DevTools 将 Widget 树中显示的 Widget 限制为项目根目录和 Flutter 中的 Widget。此过滤仅适用于检查器 Widget 树(检查器的左侧)中的 Widget,而不适用于 Widget 详情树(检查器右侧,位于与布局浏览器相同的选项卡视图中)。在 Widget 详情树中,您可以看到来自所有包的树中的所有 Widget。

为了显示其他 Widget,必须将其父目录添加到包目录中。

例如,考虑以下目录结构

project_foo
  pkgs
    project_foo_app
    widgets_A
    widgets_B

project_foo_app运行您的应用程序仅在 Widget 检查器树中显示来自project_foo/pkgs/project_foo_app的 Widget。

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

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

对包目录的更改将在下次为应用程序打开 Widget 检查器时保留。

其他资源

#

有关检查器通常可能实现的功能的演示,请参阅DartConf 2018 演讲,该演讲演示了 IntelliJ 版本的 Flutter 检查器。

要了解如何使用 DevTools 可视化调试布局问题,请查看一个指导性的Flutter 检查器教程