DevTools
学习在开发 Flutter 应用时使用 Dart DevTools。
学习使用 widget 检查器和属性编辑器来调试布局问题,并实时试验属性。
你将完成的内容
步骤
1
简介
简介
随着 Flutter 应用日益复杂,理解各个 widget 属性如何影响 UI 变得越来越重要。 Dart 和 Flutter DevTools 为你提供了两个特别实用的功能: widget 检查器 和 属性编辑器。
首先,在应用以调试模式运行时,通过运行以下命令启动 DevTools。请在 与应用运行位置不同的终端窗口 中运行此命令:
dart devtools
运行此命令会启动 DevTools 服务器,并在浏览器中打开界面。
要将 DevTools 连接到你正在运行的应用:
-
在运行应用的终端中找到打印的 DevTools URL (例如:
Serving DevTools at http://127.0.0.1:9101)。 复制此 URL。
将其粘贴到 DevTools 浏览器页面的连接栏中。
2
widget 检查器
widget 检查器
widget 检查器让你可视化和探索 widget 树。它帮助你理解 UI 的布局,并识别哪些 widget 负责屏幕的不同部分。针对你目前构建的应用运行后,检查器如下所示:
考虑你在本节中创建的 GamePage widget:
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 中的用法:
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(Row
或 Column)内,以及可滚动区域内,例如 ListView
或 ScrollView
子类。
例如,ListView 会尝试扩展以适应其交叉方向上的可用空间。比如它是一个垂直滚动的块,试图与其父级一样宽。如果你将垂直滚动的 ListView 嵌套在水平滚动的 ListView 内,内部列表会尝试尽可能宽,而由于外部列表在该方向上可滚动,因此宽度是无限的。
或许你在构建 Flutter 应用时最常遇到的错误是由于不正确地使用布局 widget。此错误被称为「无界约束」错误。
观看以下视频,了解如何发现并解决此问题。
4
属性编辑器
属性编辑器
当你在 widget 检查器中选择一个 widget 时,属性编辑器会显示该所选 widget 的所有属性。这是一个强大的工具,用于理解 widget 为何呈现当前外观,并实时试验属性值的更改。
查看前面 Tile widget 的 build 方法:
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 以查看 border 和 color
属性。
对于许多属性,你甚至可以在属性编辑器中直接修改其值。例如,要快速测试 Tile widget 中 Container 的不同 width
或 height 效果,可在属性编辑器中更改数值。该工具会直接将此更新写回磁盘上的 .dart 源文件,让你在保存或触发热重载后立即在运行中的应用上查看视觉更新。这让你能够快速迭代 UI 设计。
5
回顾
回顾
你完成的内容
以下是你本课构建与学习内容的摘要。使用 widget 检查器探索了应用的 widget 树
widget 检查器让你可视化整个 widget 树,选择任意 widget 以查看其属性,并直接跳转到其源代码。它是理解应用结构的重要工具。
了解了常见布局问题
你学习了 无界约束,这是 Flutter 开发中最常见的错误之一。当 Row、Column 或 ListView
等 widget 收到无限约束时就会发生这种情况。现在你可以在遇到这些问题时识别并修复它们。
实时试验了属性
属性编辑器显示所选 widget 的所有属性,并让你直接在磁盘上修改值,保存或触发热重载后即可立即查看更新。这让你在微调 UI 时能够快速迭代。
6
自测
自测
DevTools 测验
1 / 2-
在 widget 树中使用过多 StatefulWidget。
不正确。
使用 StatefulWidget 不会导致无界约束。
-
将试图无限扩展的 widget 放在可滚动或 flex 容器中,且未提供适当约束。
正确!
例如 Row 内的 ListView,或嵌套的可滚动组件,可能收到无限约束并失败。
-
更改数据后忘记调用 setState。
不正确。
未调用 setState 会导致 UI 不更新,而非约束错误。
-
使用 Container 时未指定颜色。
不正确。
颜色是可选的,与布局约束无关。
-
自动为你的 widget 生成单元测试。
不正确。
Widget Inspector 用于可视化和调试,而非生成测试。
-
可视化 widget 树,选择 widget 以查看其属性,并跳转到源代码。
正确!
Widget Inspector 让你探索应用结构、检查 widget 属性,并导航到相应的源代码。
-
直接将应用部署到应用商店。
不正确。
部署需单独处理;Widget Inspector 用于调试。
-
编辑应用的主题颜色和排版。
不正确。
主题编辑需要修改代码;Widget Inspector 用于检查当前状态。
除非另有说明,本文档之所提及适用于 Flutter 3.44.0 版本。本页面最后更新时间:2026-06-18。查看文档源码 或者 为本页面内容提出建议。