有關如何在不同 IDE 中查詢 DevTools 頁面的資訊,請參閱 DevTools 概覽

它是什麼?

#

Flutter Widget Inspector 是一個強大的工具,用於視覺化和探索 Flutter Widget 樹。Flutter 框架使用 Widget 作為核心構建塊,用於從控制元件(如文字、按鈕和切換按鈕)到佈局(如居中、填充、行和列)的各種內容。Inspector 可幫助您視覺化和探索 Flutter Widget 樹,並可用於以下目的:

  • 理解現有佈局
  • 診斷佈局問題

Screenshot of the Flutter inspector window

新的 Flutter Inspector

#

作為 Flutter 3.29 的一部分,新的 Flutter Inspector 預設啟用。但是,您可以從 Inspector 設定對話方塊 中停用它。

視覺化除錯佈局問題

#

以下是 Inspector 工具欄中可用功能的指南。當空間有限時,圖示用作標籤的可視版本。

Select widget mode button 選擇 Widget 模式:啟用此按鈕可選擇裝置上的 Widget 進行檢查。瞭解更多資訊,請檢視 檢查 Widget

Show implementation widgets button 顯示實現 Widget:啟用此按鈕可在 Widget 樹中顯示實現 Widget。瞭解更多資訊,請檢視 使用 Widget 樹

Refresh tree icon 重新整理樹
重新載入當前的 Widget 資訊。
Slow animations icon 慢速動畫
將動畫執行速度放慢 5 倍,以幫助微調它們。
Show guidelines mode icon 顯示輔助線
疊加輔助線以幫助修復佈局問題。
Show baselines icon 顯示基線
顯示用於對齊文字的基線。可用於檢查文字是否已對齊。
Highlight repaints icon 高亮重繪
顯示在元素重繪時會改變顏色的邊框。有助於查詢不必要的重繪。
Highlight oversized images icon 高亮過大圖片
透過反轉顏色並翻轉它們來高亮顯示佔用過多記憶體的圖片。

檢查 Widget

#

您可以瀏覽互動式 Widget 樹以檢視附近的 Widget 並檢視其欄位值。

要定位 Widget 樹中的單個 UI 元素,請單擊工具欄中的 **選擇 Widget 模式** 按鈕。這會將裝置上的應用置於“Widget 選擇”模式。單擊應用 UI 中的任何 Widget;這會選擇 Widget 在應用螢幕上,並滾動 Widget 樹到相應的節點。再次切換 **選擇 Widget 模式** 按鈕可退出 Widget 選擇模式。

在除錯佈局問題時,關鍵欄位是 sizeconstraints 欄位。約束向下傳遞到樹,而大小則向上反饋。有關此工作原理的更多資訊,請參閱 理解約束

Flutter Widget 樹

#

Flutter Widget 樹可讓您視覺化、理解和導航應用的 Widget 樹。

Image of Flutter inspector with Widget Tree highlighted

使用 Widget 樹

#

檢視專案中建立的 Widget

#

預設情況下,Flutter Widget 樹包含在專案根目錄中建立的所有 Widget。

Widget 的父子關係由一條垂直線(如果父 Widget 只有一個子項)或透過縮排(如果父 Widget 有多個子項)表示。

例如,對於以下 Widget 樹的部分

Image of widget tree section

  • Padding 只有一個子項 Row
  • Row 有三個子項:IconSizedBoxFlexible
  • Flexible 只有一個子項 Column
  • Column 有四個子項:TextTextSizedBoxDivider

檢視所有 Widget

#

要檢視 Widget 樹中的所有 Widget,包括那些在專案外建立的 Widget,請開啟“顯示實現 Widget”。

實現 Widget 以比專案中建立的 Widget 更淺的字型顯示,從而在視覺上區分它們。它們也隱藏在可摺疊組後面,可以透過內聯展開按鈕進行展開。

例如,這裡是與上面相同的 Widget 樹部分,顯示了實現 Widget

Image of widget tree section showing implementation widgets

  • Icon 下面摺疊了五個實現 Widget
  • 兩個 Text Widget 都有 RichText 實現 Widget 子項
  • Divider 下面摺疊了九個實現 Widget

Flutter Widget Explorer

#

Flutter Widget Explorer 可幫助您更好地理解檢查的 Widget。

Image of Flutter inspector with Widget Explorer highlighted

使用 Widget Explorer

#

在 Flutter Inspector 中,選擇一個 Widget。Widget Explorer 將顯示在視窗的右側。

根據所選 Widget,Widget Explorer 將包含一個或多個以下項:

  • Widget 屬性選項卡
  • Flex Explorer 選項卡
  • Render object 選項卡

Widget 屬性選項卡

#

Image of widget properties tab

屬性選項卡顯示您的 Widget 佈局的迷你檢視,包括寬度、高度和填充,以及該 Widget 上的屬性列表。

這些屬性包括值是否與屬性引數的預設值匹配。

Render object 選項卡

#

Image of render object tab

Render object 選項卡顯示設定在所選 Flutter Widget 的 render object 上的所有屬性。

Flex Explorer 選項卡

#

Image of flex explorer tab

當您選擇一個 Flex Widget(例如,RowColumnFlex)或 Flex Widget 的直接子項時,Flex Explorer 工具將出現在 Widget Explorer 中。

Flex Explorer 工具視覺化 Flex Widget 及其子項的佈局方式。Explorer 識別主軸和交叉軸,以及每個軸的當前對齊方式(例如,start、end 和 spaceBetween)。它還顯示 flex 因子、flex fit 和佈局約束等詳細資訊。

此外,Explorer 還顯示佈局約束衝突和渲染溢位錯誤。衝突的佈局約束顯示為紅色,溢位錯誤則以標準的“黃色膠帶”模式顯示,就像在執行的裝置上看到的那樣。這些視覺化旨在提高對溢位錯誤發生原因以及如何修復它們的理解。

The flex explorer showing errors and device inspector

單擊 Flex Explorer 中的 Widget 會映象在裝置上 Inspector 中的選擇。為此需要啟用 **選擇 Widget 模式**。要啟用它,請單擊 Inspector 中的 **選擇 Widget 模式** 按鈕。

The Select Widget Mode button in the inspector

對於 flex 因子、flex fit 和對齊等某些屬性,您可以透過 Explorer 中的下拉列表修改該值。修改 Widget 屬性時,您會看到新值不僅在 Flex Explorer 中反映出來,而且還在執行 Flutter 應用的裝置上反映出來。Explorer 在屬性更改時進行動畫處理,以便更改的效果清晰可見。從佈局 Explorer 所做的 Widget 屬性更改不會修改您的原始碼,並在熱過載時恢復。

可互動屬性
#

Flex Explorer 支援修改 mainAxisAlignmentcrossAxisAlignmentFlexParentData.flex。未來,我們可能會新增對其他屬性的支援,例如 mainAxisSizetextDirectionFlexParentData.fit

mainAxisAlignment
#

The flex explorer changing main axis alignment

支援的值

  • MainAxisAlignment.start
  • MainAxisAlignment.end
  • MainAxisAlignment.center
  • MainAxisAlignment.spaceBetween
  • MainAxisAlignment.spaceAround
  • MainAxisAlignment.spaceEvenly
crossAxisAlignment
#

The flex explorer changing cross axis alignment

支援的值

  • CrossAxisAlignment.start
  • CrossAxisAlignment.center
  • CrossAxisAlignment.end
  • CrossAxisAlignment.stretch
FlexParentData.flex
#

The flex explorer changing flex factor

Flex Explorer 在 UI 中支援 7 種 Flex 選項(null、0、1、2、3、4、5),但實際上 Flex Widget 子項的 flex 因子可以是任何整數。

Flexible.fit
#

The flex explorer changing fit

Flex Explorer 支援兩種不同型別的 FlexFitloosetight

視覺化除錯

#

Flutter Inspector 提供了多種視覺化除錯應用的方法。

Inspector visual debugging options

慢速動畫

#

啟用此選項後,動畫執行速度會放慢 5 倍,以便於視覺化檢查。如果您想仔細觀察和調整不那麼理想的動畫,這將非常有用。

也可以在程式碼中設定此項

dart
import 'package:flutter/scheduler.dart';

void setSlowAnimations() {
  timeDilation = 5.0;
}

這會將動畫速度減慢 5 倍。

另請參閱

#

以下連結提供了更多資訊。

以下螢幕錄影顯示了放慢動畫前後的效果。

Screen recording showing normal animation speed Screen recording showing slowed animation speed

顯示輔助線

#

此功能會在應用上繪製輔助線,顯示渲染框、對齊方式、填充、滾動檢視、剪裁和間距。

此工具可用於更好地理解您的佈局。例如,透過查詢不需要的填充或理解 Widget 對齊方式。

您也可以在程式碼中啟用此功能

dart
import 'package:flutter/rendering.dart';

void showLayoutGuidelines() {
  debugPaintSizeEnabled = true;
}

渲染框

#

繪製到螢幕上的 Widget 會建立一個 渲染框,這是 Flutter 佈局的構建塊。它們顯示為亮藍色邊框。

Screenshot of render box guidelines

對齊方式

#

對齊方式顯示為黃色箭頭。這些箭頭顯示 Widget 相對於其父項的垂直和水平偏移量。例如,此按鈕的圖示顯示為由四個箭頭居中。

Screenshot of alignment guidelines

Padding

#

填充顯示為半透明藍色背景。

Screenshot of padding guidelines

滾動檢視

#

具有滾動內容的 Widget(如列表檢視)顯示為綠色箭頭。

Screenshot of scroll view guidelines

剪裁

#

剪裁,例如在使用 ClipRect Widget 時,顯示為帶有剪刀圖示的虛線粉色線條。

Screenshot of clip guidelines

間距

#

Spacer Widget 顯示為灰色背景,例如這個沒有子項的 SizedBox

Screenshot of spacer guidelines

顯示基線

#

此選項使所有基線可見。基線是用於定位文字的水平線。

這對於檢查文字是否在垂直方向上精確對齊很有用。例如,下圖中的文字基線略有不對齊。

Screenshot with show baselines enabled

可以使用 Baseline Widget 來調整基線。

在任何設定了基線的 渲染框 上都會繪製一條線;字母基線顯示為綠色,表意基線顯示為黃色。

您也可以在程式碼中啟用此功能

dart
import 'package:flutter/rendering.dart';

void showBaselines() {
  debugPaintBaselinesEnabled = true;
}

高亮重繪

#

此選項會在所有 渲染框 上繪製邊框,每次該框重繪時,邊框顏色都會改變。

這種旋轉的彩虹色有助於查詢應用中重繪過於頻繁並可能損害效能的部分。

例如,一個小的動畫可能導致整個頁面在每一幀上重繪。將動畫包裝在 RepaintBoundary Widget 中可以將重繪限制在動畫本身。

這裡,進度指示器導致其容器重繪。

dart
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()),
    );
  }
}

Screen recording of a whole screen repainting

將進度指示器包裝在 RepaintBoundary 中只會導致螢幕的那一部分重繪。

dart
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()),
      ),
    );
  }
}

Screen recording of a just a progress indicator repainting

RepaintBoundary Widget 有其權衡。它們可以幫助提高效能,但它們也有建立新畫布的開銷,這會佔用額外的記憶體。

您也可以在程式碼中啟用此選項

dart
import 'package:flutter/rendering.dart';

void highlightRepaints() {
  debugRepaintRainbowEnabled = true;
}

高亮過大圖片

#

此選項透過反轉顏色並垂直翻轉它們來高亮顯示過大的圖片。

A highlighted oversized image

高亮顯示的圖片比必需的佔用了更多的記憶體;例如,一張 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 建構函式上的 cacheHeightcacheWidth 引數。

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

  @override
  Widget build(BuildContext context) {
    return Image.asset('dash.png', cacheHeight: 213, cacheWidth: 392);
  }
}

這會使引擎以指定的大小解碼此影像,並減少記憶體使用(解碼和儲存仍然比縮小影像資源本身更昂貴)。影像會根據佈局約束或寬度和高度進行渲染,而不管這些引數如何。

此屬性也可以在程式碼中設定

dart
void showOversizedImages() {
  debugInvertOversizedImages = true;
}

更多資訊

#

您可以在以下連結瞭解更多資訊:

跟蹤 Widget 建立

#

Flutter Inspector 的部分功能基於對應用程式程式碼進行插裝,以便更好地理解建立 Widget 的源位置。源插裝允許 Flutter Inspector 以類似於 UI 在原始碼中的定義方式呈現 Widget 樹。沒有它,Widget 樹中的節點樹會更深,並且更難理解執行時 Widget 層級結構與應用程式 UI 的對應關係。

您可以透過將 --no-track-widget-creation 傳遞給 flutter run 命令來停用此功能。

以下是啟用和停用跟蹤 Widget 建立時的 Widget 樹可能外觀的示例。

啟用跟蹤 Widget 建立(預設)

The widget tree with track widget creation enabled

停用跟蹤 Widget 建立(不推薦)

The widget tree with track widget creation disabled

此功能可防止在除錯構建中將其他方面相同的 const Widget 視為相等。有關更多詳細資訊,請參閱關於 除錯時常見問題 的討論。

Inspector 設定

#

The Flutter Inspector Settings dialog

啟用懸停檢查

#

將滑鼠懸停在任何 Widget 上都會顯示其屬性和值。

切換此值可啟用或停用懸停檢查功能。

啟用 Widget 樹自動重新整理

#

啟用後,Widget 樹會在熱過載或導航事件後自動重新整理。

使用舊版 Inspector

#

啟用後,請使用 舊版 Inspector 而不是新 Inspector。

包目錄

#

預設情況下,DevTools 將 Widget 樹中顯示的 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,請將 project_foo 新增到包目錄中。

您對包目錄的更改將在下次為應用開啟 Widget Inspector 時保留。

其他資源

#

要了解 Inspector 的一般功能,請參閱 DartConf 2018 演講,其中演示了 Flutter Inspector 的 IntelliJ 版本。

要了解如何使用 DevTools 視覺化除錯佈局問題,請檢視有關 Flutter Inspector 教程 的指南。