使用 Flutter Inspector
瞭解如何使用 Flutter Inspector 來探索 Flutter 應用的 Widget 樹。
有關如何在不同 IDE 中查詢 DevTools 螢幕的資訊,請檢視 DevTools 概覽。
它是什麼?
#Flutter Widget Inspector 是一個強大的工具,用於視覺化和探索 Flutter Widget 樹。Flutter 框架使用 Widget 作為核心構建塊,涵蓋了從控制元件(如文字、按鈕和開關)到佈局(如居中、內邊距、行和列)的所有內容。Inspector 可幫助您視覺化和探索 Flutter Widget 樹,並可用於以下目的:
- 理解現有的佈局
- 診斷佈局問題
全新的 Flutter Inspector
#作為 Flutter 3.29 的一部分,全新的 Flutter Inspector 已預設啟用。不過,您可以從 Inspector 設定對話方塊中將其停用。
視覺化除錯佈局問題
#以下是 Inspector 工具欄中可用功能的指南。當空間有限時,圖示將作為標籤的視覺版本使用。
-
- 選擇 Widget 模式
-
啟用此按鈕以在裝置上選擇要檢查的 Widget。要了解更多資訊,請檢視 檢查 Widget。
-
- 顯示實現類 Widget
-
啟用此按鈕以在 Widget 樹中顯示實現類 Widget。要了解更多資訊,請檢視 使用 Widget 樹。
-
重新整理樹 重新載入當前 Widget 資訊。
-
減慢動畫速度 將動畫執行速度放慢 5 倍,以幫助微調動畫。
-
顯示參考線 疊加顯示參考線,以幫助修復佈局問題。
-
顯示基準線 -
顯示用於對齊文字的基準線。這對於檢查文字是否對齊非常有用。
-
高亮顯示重繪 -
顯示在元素重繪時會變色的邊框。對於查詢不必要的重繪非常有用。
-
高亮顯示過大的圖片 -
透過反轉顏色並翻轉圖片,高亮顯示記憶體佔用過大的圖片。
檢查 Widget
#您可以瀏覽互動式 Widget 樹來檢視相鄰的 Widget 並檢視它們的欄位值。
要定位 Widget 樹中的各個 UI 元素,請點選工具欄中的選擇 Widget 模式按鈕。這會將裝置上的應用置於“Widget 選擇”模式。點選應用 UI 中的任意 Widget;這會在應用螢幕上選擇該 Widget,並將 Widget 樹滾動到相應的節點。再次切換選擇 Widget 模式按鈕即可退出該模式。
除錯佈局問題時,需要檢視的關鍵欄位是 size 和 constraints。約束向下傳遞,大小向上傳遞。有關此工作原理的詳細資訊,請參閱 理解約束。
Flutter Widget 樹
#Flutter Widget 樹允許您視覺化、理解和導航應用的 Widget 樹。
使用 Widget 樹
#檢視專案中建立的 Widget
#預設情況下,Flutter Widget 樹包含根專案目錄中建立的所有 Widget。
Widget 的父子關係由單條垂直線(如果父 Widget 只有一個子 Widget)或縮排(如果父 Widget 有多個子 Widget)表示。
例如,對於 Widget 樹的以下部分
Padding有一個子項Row-
Row有三個子項:Icon,SizedBox和Flexible Flexible有一個子項Column-
Column有四個子項:Text,Text,SizedBox和Divider
檢視所有 Widget
#如果想檢視 Widget 樹中的所有 Widget(包括在專案外建立的 Widget),請開啟“顯示實現類 Widget”。
實現類 Widget 以較淺的字型顯示,與專案中建立的 Widget 形成視覺區分。它們也隱藏在可摺疊的分組中,可以透過內聯展開按鈕進行展開。
例如,這裡是與上述相同部分的 Widget 樹,但顯示了實現類 Widget
Icon下方摺疊了五個實現類 Widget- 兩個
TextWidget 都有RichText實現類 Widget 子項 Divider下方摺疊了九個實現類 Widget
Flutter Widget 瀏覽器
#Flutter Widget 瀏覽器可幫助您更好地理解所檢查的 Widget。
使用 Widget 瀏覽器
#在 Flutter Inspector 中選擇一個 Widget。Widget 瀏覽器將顯示在視窗右側。
根據所選的 Widget,Widget 瀏覽器將包含以下一個或多個內容
- Widget 屬性選項卡
- Flex 瀏覽器選項卡
- 渲染物件選項卡
Widget 屬性選項卡
#
屬性選項卡會顯示 Widget 佈局的微檢視,包括寬度、高度和內邊距,以及該 Widget 的屬性列表。
這些屬性包括該值是否與屬性引數的預設值匹配。
渲染物件選項卡
#
渲染物件選項卡顯示所選 Flutter Widget 的渲染物件上設定的所有屬性。
Flex 瀏覽器選項卡
#
當您選擇一個 Flex Widget(例如 Row, Column, Flex)或 Flex Widget 的直接子項時,Flex 瀏覽器工具將出現在 Widget 瀏覽器中。
Flex 瀏覽器工具可視化了 Flex Widget 及其子項的佈局方式。該瀏覽器可識別主軸和交叉軸,以及每個軸的當前對齊方式(例如 start、end 和 spaceBetween)。它還顯示諸如彈性因子 (flex factor)、彈性適配 (flex fit) 和佈局約束等詳細資訊。
此外,瀏覽器還會顯示佈局約束衝突和渲染溢位錯誤。違規的佈局約束顯示為紅色,溢位錯誤則呈現為標準的“黃色膠帶”圖案,就像在執行中的裝置上看到的那樣。這些視覺化旨在提高對溢位錯誤發生原因以及如何修復它們的理解。
在 Flex 瀏覽器中點選 Widget 會對映到裝置上的 Inspector 選擇。為此需要啟用選擇 Widget 模式。要啟用它,請點選 Inspector 中的選擇 Widget 模式按鈕。
對於某些屬性(如彈性因子、彈性適配和對齊方式),您可以透過瀏覽器中的下拉列表修改其值。修改 Widget 屬性時,您不僅會在 Flex 瀏覽器中看到新值,還會即時反映在執行 Flutter 應用的裝置上。瀏覽器會在屬性更改時產生動畫效果,以便清晰地呈現更改的影響。透過佈局瀏覽器所做的 Widget 屬性更改不會修改您的原始碼,並且在熱過載時會恢復。
互動式屬性
#Flex 瀏覽器支援修改 mainAxisAlignment, crossAxisAlignment 和 FlexParentData.flex。將來,我們可能會增加對其他屬性的支援,例如 mainAxisSize, textDirection 和 FlexParentData.fit。
mainAxisAlignment
支援的值
MainAxisAlignment.startMainAxisAlignment.endMainAxisAlignment.centerMainAxisAlignment.spaceBetweenMainAxisAlignment.spaceAroundMainAxisAlignment.spaceEvenly
crossAxisAlignment
支援的值
CrossAxisAlignment.startCrossAxisAlignment.centerCrossAxisAlignment.endCrossAxisAlignment.stretch
FlexParentData.flex
Flex 瀏覽器在 UI 中支援 7 個彈性選項(null, 0, 1, 2, 3, 4, 5),但從技術上講,Flex Widget 子項的彈性因子可以是任何整數。
Flexible.fit
Flex 瀏覽器支援兩種不同型別的 FlexFit:loose 和 tight。
視覺化除錯
#Flutter Inspector 提供了多種視覺化除錯應用的選擇。
減慢動畫速度
#啟用後,此選項會將動畫執行速度放慢 5 倍,以便於進行視覺檢查。如果您想仔細觀察並微調看起來不太對勁的動畫,這非常有用。
也可以在程式碼中設定:
import 'package:flutter/scheduler.dart';
void setSlowAnimations() {
timeDilation = 5.0;
}
這會將動畫速度放慢 5 倍。
另請參閱
#以下連結提供了更多資訊。
以下螢幕錄製顯示了減慢動畫速度前後的對比。
顯示參考線
#此功能會在應用上繪製參考線,顯示渲染框、對齊方式、內邊距、滾動檢視、裁剪區域和間距元件。
此工具可用於更好地理解您的佈局。例如,透過查詢不需要的內邊距或理解 Widget 對齊方式。
您也可以在程式碼中啟用它:
import 'package:flutter/rendering.dart';
void showLayoutGuidelines() {
debugPaintSizeEnabled = true;
}
渲染框
#在螢幕上進行繪製的 Widget 會建立一個 渲染框 (RenderBox),這是 Flutter 佈局的構建塊。它們顯示為亮藍色的邊框。
對齊方式
#對齊方式用黃色箭頭表示。這些箭頭顯示了 Widget 相對於其父項的垂直和水平偏移量。例如,該按鈕的圖示透過四個箭頭顯示為居中狀態。
Padding
#內邊距顯示為半透明的藍色背景。
滾動檢視
#具有滾動內容的 Widget(如列表檢視)用綠色箭頭表示。
裁剪
#裁剪(例如使用 ClipRect Widget 時)顯示為帶有剪刀圖示的粉紅色虛線。
間距元件
#Spacer Widget 顯示為灰色背景,例如這個沒有子項的 SizedBox。
顯示基準線
#此選項使所有基準線可見。基準線是用於定位文字的水平線。
這對於檢查文字是否精確垂直對齊非常有用。例如,以下螢幕截圖中的文字基準線略有不對齊。
Baseline Widget 可用於調整基準線。
系統會在任何設定了基準線的 渲染框 上繪製一條線;字母基準線顯示為綠色,表意文字基準線顯示為黃色。
您也可以在程式碼中啟用它:
import 'package:flutter/rendering.dart';
void showBaselines() {
debugPaintBaselinesEnabled = true;
}
高亮顯示重繪
#此選項會在所有 渲染框 周圍繪製一個邊框,每次該框重繪時顏色都會改變。
這種旋轉的彩虹色對於查詢應用中重繪過於頻繁且可能影響效能的部分非常有用。
例如,一個小動畫可能會導致整個頁面在每一幀都重繪。將動畫包裝在 RepaintBoundary Widget 中,可將重繪限制在僅該動畫區域內。
這裡,進度指示器導致其容器進行了重繪。
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;
}
高亮顯示過大的圖片
#此選項透過反轉顏色並垂直翻轉圖片,高亮顯示過大的圖片。
高亮顯示的圖片佔用的記憶體超過了必要水平;例如,一張以 100x100 畫素顯示的大型 5MB 圖片。
此類圖片會導致效能不佳,尤其是在低端裝置上。當您在列表檢視中擁有許多圖片時,這種效能損耗會累積。有關每張圖片的資訊會列印在除錯控制檯中。
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;
}
更多資訊
#您可以透過以下連結瞭解更多資訊。
追蹤 Widget 建立
#Flutter Inspector 的部分功能基於對應用程式程式碼進行檢測,以便更好地理解 Widget 的建立位置。原始碼檢測允許 Flutter Inspector 以類似於 UI 在原始碼中定義的方式呈現 Widget 樹。如果沒有它,Widget 樹中的節點層級會深得多,並且很難理解執行時 Widget 層級結構如何對應於應用程式的 UI。
您可以透過向 flutter run 命令傳遞 --no-track-widget-creation 來停用此功能。
以下是啟用和停用“追蹤 Widget 建立”後 Widget 樹外觀的示例。
啟用“追蹤 Widget 建立”(預設)
停用“追蹤 Widget 建立”(不推薦)
此功能可防止原本相同的 const Widget 在除錯版本中被視為相等。有關更多詳細資訊,請參閱關於除錯時常見問題的討論。
Inspector 設定
#
啟用懸停檢查
#懸停在任何 Widget 上都會顯示其屬性和值。
切換此值可啟用或停用懸停檢查功能。
啟用 Widget 樹自動重新整理
#啟用後,Widget 樹會在熱過載或導航事件後自動重新整理。
使用舊版 Inspector
#啟用後,請使用舊版 Inspector 而不是新版 Inspector。
包目錄
#預設情況下,DevTools 將 Widget 樹中顯示的 Widget 限制為在專案根目錄中建立的 Widget。要檢視所有 Widget(包括在專案根目錄外建立的),請切換開啟 顯示實現類 Widget。
為了在預設 Widget 樹中包含其他 Widget,必須將其父目錄新增到“包目錄”中。
例如,考慮以下目錄結構:
project_foo
pkgs
project_foo_app
widgets_A
widgets_B
從 project_foo_app 執行應用,僅在 Widget Inspector 樹中顯示來自 project_foo/pkgs/project_foo_app 的 Widget。
要顯示來自 widgets_A 的 Widget,請將 project_foo/pkgs/widgets_A 新增到包目錄中。
要在 Widget 樹中顯示來自專案根目錄的 所有 Widget,請將 project_foo 新增到包目錄中。
對包目錄所做的更改會在下次為該應用開啟 Widget Inspector 時保留。
其他資源
#有關 Inspector 功能的演示,請觀看 DartConf 2018 演講,其中演示了 IntelliJ 版的 Flutter Inspector。
要了解如何使用 DevTools 視覺化除錯佈局問題,請檢視指導性的 Flutter Inspector 教程。