flutter-fix-layout-issues

作者: flutter

使用 Dart 和 Flutter MCP 工具修復 Flutter 佈局錯誤(溢出、無限制約束)。適用於處理「RenderFlex overflowed」、「Vertical…」等問題。

npx skills add https://github.com/flutter/skills --skill flutter-fix-layout-issues

Resolving Flutter Layout Errors

Contents

Constraint Violation Diagnostics

Flutter layout operates on a strict rule: Constraints go down. Sizes go up. Parent sets position. Layout errors occur when this negotiation fails, typically due to unbounded constraints or unconstrained children.

Diagnose layout failures using the following error signatures:

  • "Vertical viewport was given unbounded height": Triggered when a scrollable widget (ListView, GridView) is placed inside an unconstrained vertical parent (Column). The parent provides infinite height, and the child attempts to expand infinitely.
  • "An InputDecorator...cannot have an unbounded width": Triggered when a TextField or TextFormField is placed inside an unconstrained horizontal parent (Row). The text field attempts to determine its width based on infinite available space.
  • "RenderFlex overflowed": Triggered when a child of a Row or Column requests a size larger than the parent's allocated constraints. Visually indicated by yellow and black warning stripes.
  • "Incorrect use of ParentData widget": Triggered when a ParentDataWidget is not a direct descendant of its required ancestor. (e.g., Expanded outside a Flex, Positioned outside a Stack).
  • "RenderBox was not laid out": A cascading side-effect error. Ignore this and look further up the stack trace for the primary constraint violation (usually an unbounded height/width error).

Layout Error Resolution Workflow

Copy and use this checklist to systematically resolve layout constraint violations.

Task Progress

  • Run the application in debug mode to capture the exact layout exception in the console.
  • Identify the primary error message (ignore cascading "RenderBox was not laid out" errors).
  • Apply the conditional fix based on the specific error type:
    • If "Vertical viewport was given unbounded height": Wrap the scrollable child (ListView, GridView) in an Expanded widget to consume remaining space, or wrap it in a SizedBox to provide an absolute height constraint.
    • If "An InputDecorator...cannot have an unbounded width": Wrap the TextField or TextFormField in an Expanded or Flexible widget.
    • If "RenderFlex overflowed": Constrain the overflowing child by wrapping it in an Expanded widget (to force it to fit) or a Flexible widget (to allow it to be smaller than the allocated space).
    • If "Incorrect use of ParentData widget": Move the ParentDataWidget to be a direct child of its required parent. Ensure Expanded/Flexible are direct children of Row/Column/Flex. Ensure Positioned is a direct child of Stack.
  • Execute Flutter hot reload.
  • Run validator -> review errors -> fix: Inspect the UI to verify the red/grey error screen or yellow/black overflow stripes are resolved. If new layout errors appear, repeat the workflow.

Examples

Fixing Unbounded Height (ListView in Column)

Input (Error State):

// Throws "Vertical viewport was given unbounded height"
Column(
  children: <Widget>[
    const Text('Header'),
    ListView(
      children: const <Widget>[
        ListTile(title: Text('Item 1')),
        ListTile(title: Text('Item 2')),
      ],
    ),
  ],
)

Output (Resolved State):

// Wrap ListView in Expanded to constrain its height to the remaining Column space
Column(
  children: <Widget>[
    const Text('Header'),
    Expanded(
      child: ListView(
        children: const <Widget>[
          ListTile(title: Text('Item 1')),
          ListTile(title: Text('Item 2')),
        ],
      ),
    ),
  ],
)

Fixing Unbounded Width (TextField in Row)

Input (Error State):

// Throws "An InputDecorator...cannot have an unbounded width"
Row(
  children: [
    const Icon(Icons.search),
    TextField(), 
  ],
)

Output (Resolved State):

// Wrap TextField in Expanded to constrain its width to the remaining Row space
Row(
  children: [
    const Icon(Icons.search),
    Expanded(
      child: TextField(),
    ),
  ],
)

Fixing RenderFlex Overflow

Input (Error State):

// Throws "A RenderFlex overflowed by X pixels on the right"
Row(
  children: [
    const Icon(Icons.info),
    const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
  ],
)

Output (Resolved State):

// Wrap the Text widget in Expanded to force it to wrap within the available constraints
Row(
  children: [
    const Icon(Icons.info),
    Expanded(
      child: const Text('This is a very long text string that will definitely overflow the available screen width and cause a RenderFlex error.'),
    ),
  ],
)

來自 flutter 的更多技能

dart-modern-features
flutter
為了尋找現代化的候選對象:
adding-release-notes
flutter
在 DevTools 發行說明中新增使用者面向的變更描述。用於在 NEXT_RELEASE_NOTES.md 檔案中記錄改進、修正或新功能。
reviewing-devtools-prs
flutter
DevTools 儲存庫專用的 PR 審查工作流程,強制執行 DevTools 風格指南與常見審查模式。用於審查以下專案中的拉取請求時…
dart-use-primary-constructors
flutter
協助使用者撰寫語法與語意正確的 Dart 主要建構子,並遷移/使用新的建構子語法、空主體分號語法、…
code-documentation
flutter
編寫有效程式碼文件的指南,包括 docstrings、JSDoc、dartdoc 和實作註解。在編寫新程式碼、新增…時使用此技能。
api-review
flutter
根據規範的 API 設計指南審查指定的程式碼。當使用者要求進行 API 審查或檢查程式碼是否符合 API 設計時,請使用此技能。
flutter-accessibility
flutter
在 Flutter 應用程式中實作 WCAG 2 與 EN 301 549 無障礙標準及自適應佈局。強制執行語意標註、觸控目標尺寸(最小 48x48 dp)以及文字對比度(小字 4.5:1,大字 3:1),涵蓋行動裝置、網頁與桌面平台。提供網頁語意初始化、互動元件包裝、基於螢幕尺寸的佈局切換,以及鍵盤/滑鼠輸入處理的決策邏輯。包含透過 FocusTraversalGroup 進行的焦點導覽管理,以及...
flutter-accessibility-audit
flutter
透過 widget_inspector 觸發無障礙掃描,並自動在原始碼中新增 Semantics 元件或補上遺漏的標籤。