旧版 Flutter Inspector

#

Screenshot of the legacy Flutter inspector window

直观调试布局问题

#

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

Select widget mode icon 选择 Widget 模式
启用此按钮可选择设备上的 Widget 进行检查。如需了解更多信息,请查看 检查 Widget
Refresh tree icon 刷新树
重新加载当前的 Widget 信息。
Slow animations icon 慢速动画
将动画速度减慢 5 倍,以便进行微调。
Show guidelines mode icon 显示辅助线
叠加辅助线以帮助修复布局问题。
Show baselines icon 显示基线
显示基线,用于对齐文本。这有助于检查文本是否对齐。
Highlight repaints icon 高亮重绘
显示当元素重绘时颜色会发生变化的边框。有助于查找不必要的重绘。
Highlight oversized images icon 高亮过大图片
通过反转颜色和翻转来高亮使用过多内存的图片。

检查 Widget

#

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

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

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

Flutter 布局浏览器

#

Flutter 布局浏览器可帮助您更好地理解 Flutter 布局。

有关此工具功能的概述,请参阅 Flutter Explorer 视频

在 YouTube 上新标签页观看:“DevTools 布局浏览器”

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

使用布局浏览器

#

在 Flutter Inspector 中,选择一个 Widget。布局浏览器支持 弹性布局和固定尺寸布局,并为两者提供专门的工具。

弹性布局

#

当您选择一个弹性 Widget(例如,RowColumnFlex)或弹性 Widget 的直接子项时,弹性布局工具将出现在布局浏览器中。

布局浏览器可视化了 Flex Widget 及其子项的布局方式。浏览器会识别主轴和交叉轴,以及它们各自的当前对齐方式(例如,start、end 和 spaceBetween)。它还会显示诸如 flex factor、flex fit 和布局约束等详细信息。

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

The Layout Explorer showing errors and device inspector

点击布局浏览器中的 Widget 会在设备上的 Inspector 中镜像选择。为此需要启用选择 Widget 模式。要启用它,请点击 Inspector 中的选择 Widget 模式按钮。

The Select Widget Mode button in the inspector

对于某些属性,例如 flex factor、flex fit 和 alignment,您可以通过浏览器中的下拉列表修改其值。修改 Widget 属性时,您会看到新值不仅在布局浏览器中反映出来,而且在运行 Flutter 应用的设备上也会反映出来。浏览器会根据属性更改进行动画,以便清楚地显示更改的效果。从布局浏览器进行的 Widget 属性更改不会修改您的源代码,并且会在热重载时恢复。

交互式属性
#

布局浏览器支持修改 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 种 flex 选项(null、0、1、2、3、4、5),但实际上 flex Widget 的子项的 flex 因子可以是任何整数。

Flexible.fit
#

The Layout Explorer changing fit

布局浏览器支持两种不同的 FlexFit 类型:loosetight

固定尺寸布局

#

当您选择一个不是弹性 Widget 子项的固定尺寸 Widget 时,固定尺寸布局信息将出现在布局浏览器中。您可以查看选定 Widget 及其最近的上游 RenderObject 的大小、约束和填充信息。

The Layout Explorer fixed size tool

可视化调试

#

Flutter Inspector 提供了多种选项来直观调试您的应用。

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

显示辅助线

#

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

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

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

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

void showLayoutGuidelines() {
  debugPaintSizeEnabled = true;
}

渲染框

#

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

Screenshot of render box guidelines

对齐方式

#

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

Screenshot of alignment guidelines

Padding

#

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

Screenshot of padding guidelines

滚动视图

#

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

Screenshot of scroll view guidelines

裁剪

#

裁剪(例如在使用 ClipRect Widget 时)以虚线粉色线和剪刀图标显示

Screenshot of clip guidelines

间隔符

#

间隔符 Widget 以灰色背景显示,例如这个没有子项的 SizedBox

Screenshot of spacer guidelines

显示基线

#

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

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

Screenshot with show baselines enabled

可以使用 Baseline Widget 来调整基线。

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

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

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

void showBaselines() {
  debugPaintBaselinesEnabled = true;
}

高亮重绘

#

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

这种旋转的彩虹色有助于找出应用中重绘过于频繁并可能影响性能的部分。

例如,一个小的动画可能会导致整个页面在每一帧都重绘。将动画包装在 RepaintBoundary Widget 中可以将重绘限制在仅动画部分。

此处,进度指示器导致其容器重绘

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 Widget 有其权衡。它们可以提高性能,但创建新画布也有开销,这会占用额外内存。

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

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

void highlightRepaints() {
  debugRepaintRainbowEnabled = true;
}

高亮过大图片

#

此选项通过反转颜色和垂直翻转来高亮过大的图片

A highlighted oversized image

高亮显示的图片使用的内存超过了必需;例如,一张 5MB 的大图片以 100x100 像素显示。

这些图片可能会导致性能下降,尤其是在低端设备上以及当您有很多图片时(例如在列表视图中),这种性能影响会累加。每张图片的详细信息会打印在调试控制台中

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

跟踪 Widget 创建

#

Flutter Inspector 的一部分功能基于对应用程序代码进行仪表化,以便更好地理解创建 Widget 的源位置。源仪表化允许 Flutter Inspector 以类似于在源代码中定义 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 视为相等。有关更多详细信息,请参阅关于 调试时常见问题的讨论。

Inspector 设置

#

The Flutter Inspector Settings dialog

启用悬停检查

#

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

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

包目录

#

默认情况下,DevTools 将 Widget 树中显示的 Widget 限制为项目根目录和 Flutter 的 Widget。此筛选仅适用于 Inspector Widget 树(Inspector 左侧)中的 Widget,而不适用于 Widget 详细信息树(Inspector 右侧,与布局浏览器位于同一选项卡视图中)。在 Widget 详细信息树中,您可以看到所有包中 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 教程