DevTools 必知必会系列 —— Flutter inspector
本篇文章翻译自官方的 👉Using the Flutter inspector,这篇文章是 DevTools 系列的第二篇文章,主要介绍 Inspector 工具怎么用。
往期精彩:
以下是正文
注意: Inspector 工具适用于所有的 Flutter 应用
Inspector 工具是啥?
Flutter widget inspector 是可视化与检查 Widget 树的强有力工具。Flutter framework 使用 Widget 来构建 UI,比如用于显示的 Text、Button、Switch等等,用于布局的 Center、Row、Column 等等。Inspector 帮助开发者可视化和检查 Widget 树,并且可以用于以下情况:
- 理解已经开发的布局
- 诊断布局问题
开始使用
要 debug 布局问题话,先在 debug 模式下 run 起来应用,然后在打开的 DevTools 窗口上,选择 Flutter Inspector 标签。
注意: 开发者也可以在 Android Studio/IntelliJ 中直接打开 Flutter inspector,但是开发者也可以在 DevTools 中看到更宽敞的视图
可视化地调试布局问题
下面是 Inspector 现在支持的功能,当浏览器窗口放不下这么多时,就直接放图标了。
-
Select widget mode
选中单个 Widget 进行检查
-
Refresh tree
刷新当前 Widget 信息
-
Slow animations
5倍的慢放动画以便更好的优化它们
-
Show guidelines
组件显示边框线以便检查布局问题
-
Show baselines
展示 baseline 以便检查文字的对齐问题
-
Highlight repaints
展示重绘元素的边框以便检查不必要的重绘
-
Highlight oversized images
反转颜色以及翻转的方式高亮大图
检查 Widget
在窗口浏览 Widget 树,并且查看 Widget 的字段
Select Widget Mode 模式下可以定位 UI 元素。这种模式下也可以让 APP 进入 “widget select” 模式,可以实现与窗口的联动,点击 APP 上的 UI ,同样窗口也可以选中该 UI。关闭 Select Widget Mode 也就退出了该模式。
使用 Layout Explorer
在 Flutter Inspector 的页面,选择一个 Widget。Layout Explorer 即支持 flex 布局,也支持固定大小布局,并且为这些提供了响应的工具。
Flex 布局
当开发者选择了一个 flex 组件(比如 Row
、Column
、Flex
)或者 flex 组件的直接子节点,flex 布局工具就出现在了 Layout Explorer 窗口。
Layout Explorer 可视化 Flex
Widget和它的子节点是怎么布局的。Layout Explorer 展示了主轴、交叉轴、对齐等信息。也展示了 flex 因子、flex 样式和布局约束等细节。
除此之外,Explorer 也会展示出布局约束不正常的地方,并且呈现出溢出错误。 违反布局约束是被红色标出来,溢出错误是经常看到的黄色带子。这些突出的表现想要增强错误信息:为什么出现、怎么修复。
Select Widget Mode 可以实现与设备的联动,可以点击 Select Widget Mode 按钮打开。
对于一些像 flex 因子、flex 样式、 对齐这样的属性,开发者可以在下拉框中选择。当修改 Widget 属性,开发者可以看到不仅可以在 Layout Explorer 看到效果,也可以在 Flutter App 上看到效果。Layout Explorer 用动画的方式强调属性的改变,更加醒目。Widget 属性的修改并不会真正写到代码中,hot reload 之后就变回去了。
属性交互
Layout Explorer 支持修改 mainAxisAlignment
、crossAxisAlignment
、FlexParentData.flex
属性。在后续的规划中,也支持修改 mainAxisSize
、 textDirection
和 FlexParentData.fit
等属性
mainAxisAlignment
支持的值:
MainAxisAlignment.start
MainAxisAlignment.end
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceAround
MainAxisAlignment.spaceEvenly
crossAxisAlignment
支持的值:
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.end
CrossAxisAlignment.stretch
FlexParentData.flex
Layout Explorer 在 UI 上支持 (null, 0, 1, 2, 3, 4, 5) 这几个 flex 选项,但是技术上,也可以是任意的 int 值。
Flexible.fit
Layout Explorer 支持两个不同的类型 : loose
和 tight
.
固定尺寸布局
开发者选择了☝一个固定大小的 Widget,那么固定的尺寸信息就会出现在 Layout Explorer 中。开发者可以看到大小、约束、间距以及最相关的渲染对象信息。
可视化调试
Flutter Inspector 提供了几个可视化的功能。
Slow animations
可以让动画慢放,当开发者想要仔细观察和调整不太正常的动画时比较有用。
也可以通过代码设置:
import 'package:flutter/scheduler.dart';
void setSlowAnimations() {
timeDilation = 5.0;
}
这是慢放 5 倍。
timeDilation
属性的细节可以在 👉timeDilation property 文档 这里查看。
下面的动画中,左侧是正常的,右侧是慢放的。
Show guidelines
在 APP 中绘制指导线更好的展示:渲染盒子、对齐、间距、滚动视图、裁减、间隙等等。
这个工具可以让开发者更好的检查开发的布局。比如,找到不想要的间距、理解组件的对齐等等。
也可以在代码中设置:
import 'package:flutter/rendering.dart';
void showLayoutGuidelines() {
debugPaintSizeEnabled = true;
}
Render boxes
UI 中渲染型的 Widget,会被蓝色的边框包围:
Alignments
对齐会被黄色的尖头标识。箭头表示相对于父组件的水平、垂直偏移。比如,下面的按钮就是相对于父组件的居中:
Padding
用蓝色的不透明区域表示间距:
Scroll views
带有滚动内容的 Widget 会展示绿色箭头:
Clipping
用粉红色虚线和小剪刀图标表示裁减组件,比如 ClipRect widget:
Spacers
用灰色背景表示间隙组件,比如没有子节点的 SizedBox
:
展示 baselines
这个功能可以展示文字的基线。文字基线是定位文字的水平线。
对检查文字是否垂直对齐十分有帮助。比如,下面的文字基线就有一点点🤏没对齐:
Baseline 组件可以调整基线
alphabetic 基线用绿色,ideographic 基线用黄色。
也可以通过下面的代码来打开此功能:
import 'package:flutter/rendering.dart';
void showBaselines() {
debugPaintBaselinesEnabled = true;
}
高亮重绘
这个功能下,每个 render boxes 会有一个带颜色的边框,当 box 重绘的时候,颜色就会变化。 这种颜色的变化对找到重绘的区域非常有帮助,频繁的重绘可能会影响性能。
比如,一个小小的动画可能会导致整个页面每一帧都重绘。使用 RepaintBoundary 组件包裹动画组件就会将重绘限制到动画组件上。
下面就是进度条导致的重绘:
class EverythingRepaintsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Repaint Example')),
body: Center(
child: CircularProgressIndicator(),
),
);
}
}
使用 RepaintBoundary
包裹进度组件,就能达到仅仅重绘进度组件的效果:
class AreaRepaintsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Repaint Example')),
body: Center(
child: RepaintBoundary(
child: CircularProgressIndicator(),
),
),
);
}
}
RepaintBoundary
组件需要平衡. 它在性能上会有提升,但是也会创建一个新的画布,会在占有更多的内存。
也可以通过代码来打开功能:
import 'package:flutter/rendering.dart';
void highlightRepaints() {
debugRepaintRainbowEnabled = true;
}
高亮大图
通过反转颜色和垂直翻转来强调大图:
大图会占用更多的内存,比如,100 * 100 像素的 5M 大图。
这样的图片会导致性能问题,尤其是在低端设备上,或者在列表中显示多张图片时。每个图片的信息会在 debug 控制台中打印出来:
dash.png has a display size of 213×392 but a decode size of 2130×392,
which uses an additional 2542KB.
如果图片超过了 128KB,那么就是大图了。
修复图片问题
不管怎么样,解决大图最好的办法是让图片文件更小。
如果做不到缩减图片文件,可以设置 Image
构造方法的 cacheHeight
和 cacheWidth
参数。
class ResizedImage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Image.asset(
'dash.png',
cacheHeight: 213,
cacheWidth: 392,
);
}
}
上面的代码就是让引擎用指定的大小来编解码图片,并且缩减内存。如果图片的宽高被指定了,那么就无视 cacheXX
参数。
功能也可以通过代码来打开:
import 'package:flutter/painting.dart';
void showOversizedImages() {
debugInvertOversizedImages = true;
}
关于 debugInvertOversizedImages
更多的细节可以在 👉Flutter documentation: debugInvertOversizedImages 查阅。
Widget 细节
选中 Details Tree tab 可以显示出选中 Widget 的细节信息
在细节树中,开发者可以看到关于 Widget 的一切信息:属性、渲染对象、子节点等等。
Widget 创建链
为了更好的找到创建 Widget 的源代码位置,Flutter inspector 的部分功能基于源代码检测。正是因为源代码检测,Flutter inspector 展示的 Widget 树才可以和开发者开发的 UI 代码类似。 我们知道真正的 Widget 树要比我们代码中开发的 Widget 树深得多,正是因为源代码检测,Flutter inspector 展示的 Widget 树才可以和我们的 UI 代码相类似。如果没有源代码检测,开发者会很难将正在的 Widget 树和代码对应起来。
开发者也可以禁用这个功能:在 flutter run
命令后面添加 --no-track-widget-creation
。
下面是功能开启和禁用的创建图。
开启状态(默认):
禁用状态:
其他资源
更细节的功能演示,可以看 👉 DartConf 2018 talk