跳转至正文

DevTools

学习在开发 Flutter 应用时使用 Dart DevTools。

学习使用 widget 检查器和属性编辑器来调试布局问题,并实时试验属性。

你将完成的内容

使用 widget 检查器探索应用的 widget 树
学习调试无界约束等布局问题
实时试验属性

步骤

1

简介

随着 Flutter 应用日益复杂,理解各个 widget 属性如何影响 UI 变得越来越重要。 Dart 和 Flutter DevTools 为你提供了两个特别实用的功能: widget 检查器属性编辑器

首先,在应用以调试模式运行时,通过运行以下命令启动 DevTools。请在 与应用运行位置不同的终端窗口 中运行此命令:

dart devtools

运行此命令会启动 DevTools 服务器,并在浏览器中打开界面。

要将 DevTools 连接到你正在运行的应用:

  1. 在运行应用的终端中找到打印的 DevTools URL (例如:Serving DevTools at http://127.0.0.1:9101)。

  2. 复制此 URL。

  3. 将其粘贴到 DevTools 浏览器页面的连接栏中。

2

widget 检查器

widget 检查器让你可视化和探索 widget 树。它帮助你理解 UI 的布局,并识别哪些 widget 负责屏幕的不同部分。针对你目前构建的应用运行后,检查器如下所示:

A screenshot of the Flutter widget inspector tool.

考虑你在本节中创建的 GamePage widget:

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

  final Game _game = Game();

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(8.0),
      child: Column(
        spacing: 5.0,
        children: [
          for (var guess in _game.guesses)
            Row(
              spacing: 5.0,
              children: [
                for (var letter in guess) Tile(letter.char, letter.type)
              ]
            ),
        ],
      ),
    );
  }
}

以及它在 MainApp 中的用法:

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(child: GamePage()),
      ),
    );
  }
}

在 widget 检查器中,你应该能看到与代码中完全相同的 widget 树:以 MaterialApp 为根,以 Scaffold 作为其 home,以 AppBar 作为其 appBar,以此类推,一直到带有 Tile 子级的 Row widget。你可以在树中选择任意 widget 以查看其属性,甚至跳转到 IDE 中的对应源代码。

3

调试布局问题

widget 检查器或许在调试布局问题时最为实用。

在某些情况下, widget 的 约束 是无界的,即无限的。这意味着最大宽度或最大高度被设置为 double.infinity。当给定无界约束时,试图尽可能大的 widget 无法正常工作,并且在调试模式下会抛出异常。

渲染 box 最终获得无界约束的最常见情况出现在 flex box widget(RowColumn)内,以及可滚动区域内,例如 ListViewScrollView 子类。

例如,ListView 会尝试扩展以适应其交叉方向上的可用空间。比如它是一个垂直滚动的块,试图与其父级一样宽。如果你将垂直滚动的 ListView 嵌套在水平滚动的 ListView 内,内部列表会尝试尽可能宽,而由于外部列表在该方向上可滚动,因此宽度是无限的。

或许你在构建 Flutter 应用时最常遇到的错误是由于不正确地使用布局 widget。此错误被称为「无界约束」错误。

观看以下视频,了解如何发现并解决此问题。

Watch on YouTube in a new tab: "Decoding Flutter: Unbounded height and width"

4

属性编辑器

当你在 widget 检查器中选择一个 widget 时,属性编辑器会显示该所选 widget 的所有属性。这是一个强大的工具,用于理解 widget 为何呈现当前外观,并实时试验属性值的更改。

A screenshot of the Flutter property editor tool.

查看前面 Tile widget 的 build 方法:

dart
class Tile extends StatelessWidget {
  const Tile(this.letter, this.hitType, {super.key});

  final String letter;
  final HitType hitType;

  @override
  Widget build(BuildContext context) {
    return Container(
      width: 60,
      height: 60,
      decoration: BoxDecoration(
        border: Border.all(color: Colors.grey.shade300),
        color: switch (hitType) {
          HitType.hit => Colors.green,
          HitType.partial => Colors.yellow,
          HitType.miss => Colors.grey,
          _ => Colors.white,
        },
      ),
    );
  }
}

如果你在 widget 检查器中选择 Tile 内的 Container widget,属性编辑器会显示其 width (60)、height (60) 以及 decoration 属性。然后你可以展开 BoxDecoration 以查看 bordercolor 属性。

对于许多属性,你甚至可以在属性编辑器中直接修改其值。例如,要快速测试 Tile widget 中 Container 的不同 widthheight 效果,可在属性编辑器中更改数值。该工具会直接将此更新写回磁盘上的 .dart 源文件,让你在保存或触发热重载后立即在运行中的应用上查看视觉更新。这让你能够快速迭代 UI 设计。

5

回顾

你完成的内容

以下是你本课构建与学习内容的摘要。
使用 widget 检查器探索了应用的 widget 树

widget 检查器让你可视化整个 widget 树,选择任意 widget 以查看其属性,并直接跳转到其源代码。它是理解应用结构的重要工具。

了解了常见布局问题

你学习了 无界约束,这是 Flutter 开发中最常见的错误之一。当 RowColumnListView 等 widget 收到无限约束时就会发生这种情况。现在你可以在遇到这些问题时识别并修复它们。

实时试验了属性

属性编辑器显示所选 widget 的所有属性,并让你直接在磁盘上修改值,保存或触发热重载后即可立即查看更新。这让你在微调 UI 时能够快速迭代。

6

自测

DevTools 测验

1 / 2
Flutter 中「无界约束」错误的常见原因是什么?
  1. 在 widget 树中使用过多 StatefulWidget。

    不正确。

    使用 StatefulWidget 不会导致无界约束。

  2. 将试图无限扩展的 widget 放在可滚动或 flex 容器中,且未提供适当约束。

    正确!

    例如 Row 内的 ListView,或嵌套的可滚动组件,可能收到无限约束并失败。

  3. 更改数据后忘记调用 setState。

    不正确。

    未调用 setState 会导致 UI 不更新,而非约束错误。

  4. 使用 Container 时未指定颜色。

    不正确。

    颜色是可选的,与布局约束无关。

你可以在 Flutter DevTools 的 Widget Inspector 中做什么?
  1. 自动为你的 widget 生成单元测试。

    不正确。

    Widget Inspector 用于可视化和调试,而非生成测试。

  2. 可视化 widget 树,选择 widget 以查看其属性,并跳转到源代码。

    正确!

    Widget Inspector 让你探索应用结构、检查 widget 属性,并导航到相应的源代码。

  3. 直接将应用部署到应用商店。

    不正确。

    部署需单独处理;Widget Inspector 用于调试。

  4. 编辑应用的主题颜色和排版。

    不正确。

    主题编辑需要修改代码;Widget Inspector 用于检查当前状态。