使用 Flutter 检查器

它是什么?

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

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

Screenshot of the Flutter inspector window

开始

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

直观调试布局问题

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

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

检查小组件

你可以浏览交互式小组件树,以查看附近的小组件及其字段值。

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

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

Flutter 布局浏览器

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

有关此工具可执行操作的概述,请参阅 Flutter Explorer 视频

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

使用布局浏览器

在 Flutter Inspector 中,选择一个组件。布局浏览器支持 Flex 布局 和固定大小布局,并针对这两种布局都提供了特定的工具。

Flex 布局

当你选择一个 Flex 组件(例如,RowColumnFlex)或 Flex 组件的直接子组件时,Flex 布局工具将出现在布局浏览器中。

布局浏览器可视化 Flex 组件及其子组件的布局方式。浏览器会识别主轴和交叉轴,以及每个轴的当前对齐方式(例如,start、end 和 spaceBetween)。它还显示了诸如 flex 因子、flex 拟合和布局约束之类的详细信息。

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

The Layout Explorer showing errors and device inspector

在布局浏览器中单击一个组件会镜像设备检查器上的选择。为此,需要启用选择组件模式。要启用它,请单击检查器中的选择组件模式按钮。

The Select Widget Mode button in the inspector

对于某些属性,如 flex 因子、flex 拟合和对齐方式,你可以通过浏览器中的下拉列表修改值。修改组件属性时,你不仅可以在布局浏览器中看到新值,还可以在运行 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 个 flex 选项(null、0、1、2、3、4、5),但从技术上讲,flex 小部件子元素的 flex 因子可以是任何整数。

Flexible.fit

The Layout Explorer changing fit

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

固定大小布局

当你选择一个不是 flex 小部件子元素的固定大小小部件时,固定大小布局信息将显示在布局资源管理器中。你可以看到所选小部件及其最近的上游 RenderObject 的大小、约束和填充信息。

The Layout Explorer fixed size tool

可视化调试

Flutter Inspector 提供了多种可视化调试应用的选项。

Inspector visual debugging options

慢动作动画

启用此选项后,动画将以慢 5 倍的速度运行,以便于直观检查。如果你想仔细观察和调整一个看起来不太正确的动画,这会很有用。

这也可以在代码中设置

import 'package:flutter/scheduler.dart';

void setSlowAnimations() {
  timeDilation = 5.0;
}

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

另请参阅

以下链接提供了更多信息。

以下屏幕录制显示了在动画变慢之前和之后的情况。

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

显示参考线

此功能会在你的应用上绘制参考线,显示渲染框、对齐、填充、滚动视图、剪辑和间隔符。

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

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

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 小组件来调整基线。

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

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

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

Screen recording of a whole screen repainting

将进度指示器包装在 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(),
        ),
      ),
    );
  }
}

Screen recording of a just a progress indicator repainting

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

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

import 'package:flutter/rendering.dart';

void highlightRepaints() {
  debugRepaintRainbowEnabled = true;
}

高亮超大图像

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

A highlighted oversized image

高亮的图像使用的内存比所需的多;例如,以 100 x 100 像素显示的大 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 参数

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;
}

更多信息

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

详细信息树

选择小部件详细信息树选项卡以显示所选小部件的详细信息树。在此,您可以收集有关小部件的属性、渲染对象和子项的有用信息。

The Details Tree view

跟踪小部件创建

Flutter 检查器功能的一部分基于对应用程序代码进行检测,以便更好地了解创建小部件的源位置。源检测允许 Flutter 检查器以类似于在源代码中定义 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

启用悬停检查

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

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

包目录

默认情况下,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 演讲,演示 Flutter 检查器的 IntelliJ 版本。

要了解如何使用 DevTools 直观地调试布局问题,请查看指导性的 Flutter 检查器教程