使用 Flutter inspector 工具
這是什麼?
Flutter widget inspector 是一個強大的工具,用於視覺化和檢視 widget 樹。 Flutter 框架層使用 widgets 作為 核心建構模組 來處理從控制項(例如文字、按鈕和切換等)到佈局(例如居中、填充、行和列等)的所有內容。 Flutter inspector 不僅可以幫助你視覺化檢視 Flutter widget 樹,還有其他的作用:
-
瞭解現有佈局
-
診斷佈局問題
開始使用
要除錯佈局問題,請在 Debug 模式 下執行應用程式,然後點選 DevTools 工具欄上的 Flutter inspector 選項開啟除錯面板。
視覺化地除錯佈局問題
下面是 Flutter inspector 工具欄中可用功能的指南。當空間有限時,將直接使用圖示展示。
-
選擇 widget 模式
-
啟用此按鈕以在裝置上選擇 widget 進行檢視。有關更多資訊,請參考 檢視 widget。
-
重新整理樹
-
重新載入當前 widget 的資訊。
-
以五分之一的速度執行動畫以便對它們進行最佳化。
-
覆蓋一層引導線以幫助調整佈局問題。
-
針對文字對齊展示文字的基線。對檢查文字是否對齊有幫助。
-
重新繪製時在圖層上依次顯示不同的顏色。
-
在執行的應用程式中高亮並反轉消耗過多記憶體的影象。
MainAxisAlignment.start
MainAxisAlignment.end
MainAxisAlignment.center
MainAxisAlignment.spaceBetween
MainAxisAlignment.spaceAround
MainAxisAlignment.spaceEvenly
CrossAxisAlignment.start
CrossAxisAlignment.center
CrossAxisAlignment.end
CrossAxisAlignment.stretch
檢查一個 widget
你可以瀏覽 widget 樹並檢視其附近的 widgets 和它們的屬性值。
要在 widget 樹中找到單個 UI 元素,請點選工具欄中的 Select Widget Mode 按鈕。這將使裝置上的應用程式進入「widget select」模式。點選應用介面上的任何 widget,將選中 widget 並將 widget 樹滾動到對應的節點。再次點選 Select Widget Mode 按鈕則退出「widget select」模式。
在除錯佈局問題時,要檢視的關鍵欄位是 size
和 constraints
。其中約束沿樹結構向下傳遞,尺寸資訊則向上返回。想要了解更多資訊,可以檢視 深入理解 Flutter 佈局約束。
Flutter 佈局瀏覽器
Flutter 佈局瀏覽器可以幫助你更好地理解 Flutter 佈局。
有關此工具的操作概述,觀看 Flutter Explorer 的介紹影片:
下面詳細介紹的文章可能對你有幫助:
使用佈局瀏覽器
從 Flutter Inspector 中,選擇一個 widget。佈局瀏覽器支援 彈性佈局 和固定大小的佈局,並且針對它們配備了特定的工具。
彈性佈局
當你選擇了一個彈性佈局 widget(例如,Row
、Column
、Flex
)或它的子 widget 時,彈性佈局工具將顯示在佈局瀏覽器中。
佈局瀏覽器會直觀的顯示 Flex
widgets 及其子元素的佈局方式。瀏覽器中還會顯示主軸和交叉軸,以及每個軸當前的對齊方式(例如,start、end 和 spaceBetween)。它還顯示了諸如彈性係數、彈性適配和佈局約束等詳細資訊。
此外,瀏覽器中還會顯示佈局約束衝突和渲染溢位錯誤。正如你在裝置上看到的那樣,違背佈局約束的地方會被標記成紅色,溢位錯誤以標準的「黃色條帶」顯示。這些視覺化的錯誤是為了讓我們更好地理解溢位錯誤發生的原因,並瞭解如何修復它們。
在 Select Widget Mode 模式下,點選佈局瀏覽器中的 widget 會同步選擇到裝置上。啟用此模式,請點選除錯面板中的 Select Widget Mode 按鈕。
你可以在佈局瀏覽器的下拉列表修改屬性值,例如彈性係數、彈性適配和對齊方式。當修改 widget 的屬性時,您會看到新的值同時在瀏覽器和執行 Flutter 應用程式的裝置上生效。瀏覽器透過動畫使更改的效果清晰可見。從佈局瀏覽器中對 widget 屬性的更改不會修改原始碼,將在熱重載時還原。
互動屬性
佈局資源管理器支援修改 mainAxisAlignment
、crossAxisAlignment
和 FlexParentData.flex
。將來,我們可能會新增對其他屬性的支援,例如 mainAxisSize
、textDirection
和 FlexParentData.fit
.
mainAxisAlignment
支援屬性:
crossAxisAlignment
支援屬性:
FlexParentData.flex
佈局瀏覽器支援設定 7 種彈性因子(null、0、1、2、3、4、5),但從技術上講,彈性 widget 子級的彈性因子可以是任何整數。
Flexible.fit
佈局瀏覽器支援兩種不同型別的 FlexFit
:loose
和 tight
。
固定大小布局
當您選擇一個固定大小的 widget 而不是彈性 widget 時,它的佈局資訊將顯示在佈局瀏覽器中。你可以看到所選 widget 及其最近的上一級 RenderObject 的大小、約束和填充資訊。
除錯視覺效果
Flutter Inspector 提供了多種以視覺化方式除錯應用的方式。以下是在 Flutter DevTools 中的 inspector 可用的選項:
慢速動畫
啟用時,動畫將以約五分之一的原有速度執行,方便對視覺效果進行檢查。當你想要仔細地觀察並除錯看起來不正常的動畫時,這個選項會非常有用。
你也可以使用程式碼設定:
import 'package:flutter/scheduler.dart';
void setSlowAnimations() {
timeDilation = 5.0;
}
這會讓動畫時長增加 5 倍(速度減慢 5 倍)。
更多內容
以下的連結提供了更多細節內容。
以下的錄屏展示了動畫減速前後的對比。
顯示引導線
該功能會在你的應用最上層繪製引導線,展示繪製區域、對齊、間距、滾動檢視、裁剪和空位填充。
這個工具能幫助你更加了解你的佈局。例如查詢不需要的填充或者理解 widget 的對齊方式。
你也可以透過程式碼啟用:
import 'package:flutter/rendering.dart';
void showLayoutGuidelines() {
debugPaintSizeEnabled = true;
}
Render boxes
RenderBox
繪製在螢幕上的 widgets 會建立一個 RenderBox,它是 Flutter 佈局的基礎建構。這些 RenderBox 會加上一個淺藍色的邊框:
對齊方式
對齊方式將以黃色箭頭展示。這些箭頭會顯示出垂直和豎屏方向上 widget 相對其父佈局的偏移。例如,這個按鈕圖示有四個箭頭表示它被居中展示:
間距
間距會以半透明的藍色背景顯示:
滾動檢視
包含滾動內容的 widget(例如 ListView)會展示綠色的箭頭:
裁剪
使用了諸如 ClipRect Widget 進行裁剪的內容,會以粉紅色的虛線加一個剪刀圖示展示:
空位填充
空位填充的 widgets 會以灰色背景展示,例如沒有 child 的 SizedBox
:
顯示基線
該選項會顯示所有的基線。基線是水平的用來定位文字的線。
在檢查文字是否垂直對齊時,基線會非常有用。例如,下圖中文字的基線稍微有一些錯位:
Baseline widget 可以用來調整基線。
在設定了基線的 RenderBox 上,都會顯示一條線。字母的基線以綠色展示,而符號的基線以黃色展示。
你也可以透過程式碼啟用:
import 'package:flutter/rendering.dart';
void showBaselines() {
debugPaintBaselinesEnabled = true;
}
高亮重繪製內容
該選項會為所有的 RenderBox 繪製一層邊框,在它們重新繪製時改變顏色。
以彩虹色譜迴圈的顏色,有利於你找到應用中頻繁重繪導致效能消耗過大的部分。
例如,一個小動畫可能會導致整個頁面一直在重繪。將動畫使用 RepaintBoundary widget 巢狀(Nesting),可以保證動畫只會導致其本身重繪。
下面是一個進度指示器導致其容器重繪的例子:
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(),
),
);
}
}
將進度指示器使用 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(),
),
),
);
}
}
RepaintBoundary
widget 也有一些額外的消耗。它們對效能有一定的幫助,但也會在建立額外的繪製畫布時增加一定的記憶體消耗。
你也可以透過程式碼啟用:
import 'package:flutter/rendering.dart';
void highlightRepaints() {
debugRepaintRainbowEnabled = true;
}
高亮尺寸過大的圖片
該選項會將尺寸過大的圖片高亮表示,並且進行垂直翻轉及色調反轉:
被高亮的圖片使用了過多的記憶體。例如一張 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
構造裡的
cacheHeight
和 cacheWidth
引數:
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;
}
更多內容
以下的連結提供了更多細節內容:
樹的詳細資訊
選擇 Details Tree 標籤展示選中 widget 的樹結構的詳細資訊。
從樹的詳細資訊中,你可以獲取有關 widget 的屬性、渲染物件和子節點等有用資訊。
追蹤 widget 建立
Flutter inspector 的部分功能是基於檢測應用程式的原始碼,以便更好地理解建立 widget 的源位置。 Flutter inspector 可以以類似於在原始碼中定義 UI 的方式呈現 widget 樹。如果沒有它,widget 樹中的組成某個節點的樹結構會更深,並且更難理解執行時 widget 的層次結構如何與應用程式的 UI 相對應。
你可以透過在 flutter run
後面新增引數 -no track widget creation
來禁用此功能。
下面是 widget 樹在啟用和不啟用追蹤 widget 建立下的範例。
啟用追蹤 widget 建立(預設):
關閉追蹤 widget 建立(不推薦):
此功能可避免在除錯建構中將其他相同的 const
的 Widgets 視為相同。有關更多詳細資訊,請參閱關於 除錯時常見問題 的討論。
其他資源
有關 Flutter inspector 常用功能的示範,請參考 DartConf 2018 talk 中基於 IntelliJ 上的示範。