SKILL.md
唯讀
名稱
flutter-fix-layout-issues
描述
使用 Dart 和 Flutter MCP 工具修復 Flutter 版面配置錯誤(溢出、無限制約束)。適用於處理「RenderFlex overflowed」、「Vertical viewport was given unbounded height」或類似版面配置問題。
解決 Flutter 版面配置錯誤
目錄
約束違規診斷
Flutter 版面配置遵循嚴格規則:約束向下傳遞。尺寸向上回報。父層設定位置。 當此協商失敗時,就會發生版面配置錯誤,通常是因為無限制約束或未受約束的子元件。
根據以下錯誤特徵診斷版面配置失敗:
- 「Vertical viewport was given unbounded height」:當可滾動元件(
ListView、GridView)被放置在無垂直約束的父層(Column)內部時觸發。父層提供無限高度,子元件嘗試無限擴展。 - 「An InputDecorator...cannot have an unbounded width」:當
TextField或TextFormField被放置在無水平約束的父層(Row)內部時觸發。文字欄位嘗試根據無限可用空間決定其寬度。 - 「RenderFlex overflowed」:當
Row或Column的子元件請求的尺寸大於父層分配的約束時觸發。視覺上會出現黃色和黑色警告條紋。 - 「Incorrect use of ParentData widget」:當
ParentDataWidget不是其必要祖先的直接後代時觸發(例如,Expanded不在Flex內,Positioned不在Stack內)。 - 「RenderBox was not laid out」:這是一個連鎖副作用錯誤。請忽略此錯誤,並在堆疊追蹤中向上尋找主要的約束違規(通常是無限制高度/寬度錯誤)。
版面配置錯誤解決流程
複製並使用此檢查清單,系統性地解決版面配置約束違規。
任務進度
- [ ] 以除錯模式執行應用程式,在控制台中擷取確切的版面配置例外。
- [ ] 識別主要錯誤訊息(忽略連鎖的「RenderBox was not laid out」錯誤)。
- [ ] 根據特定錯誤類型套用條件式修復:
- 如果出現「Vertical viewport was given unbounded height」:將可滾動子元件(
ListView、GridView)包在Expanded元件中以佔用剩餘空間,或將其包在SizedBox中以提供絕對高度約束。 - 如果出現「An InputDecorator...cannot have an unbounded width」:將
TextField或TextFormField包在Expanded或Flexible元件中。 - 如果出現「RenderFlex overflowed」:將溢出的子元件包在
Expanded元件中(強制其適應)或Flexible元件中(允許其小於分配的空間)。 - 如果出現「Incorrect use of ParentData widget」:將
ParentDataWidget移動為其必要父層的直接子元件。確保Expanded/Flexible是Row/Column/Flex的直接子元件。確保Positioned是Stack的直接子元件。
- 如果出現「Vertical viewport was given unbounded height」:將可滾動子元件(
- [ ] 執行 Flutter 熱重新載入。
- [ ] 執行驗證器 -> 檢視錯誤 -> 修復:檢查 UI,確認紅色/灰色錯誤畫面或黃色/黑色溢出條紋已解決。如果出現新的版面配置錯誤,請重複此流程。
範例
修復無限制高度(Column 中的 ListView)
輸入(錯誤狀態):
// 拋出「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')),
],
),
],
)
輸出(已解決狀態):
// 將 ListView 包在 Expanded 中,將其高度限制在 Column 的剩餘空間
Column(
children: <Widget>[
const Text('Header'),
Expanded(
child: ListView(
children: const <Widget>[
ListTile(title: Text('Item 1')),
ListTile(title: Text('Item 2')),
],
),
),
],
)
修復無限制寬度(Row 中的 TextField)
輸入(錯誤狀態):
// 拋出「An InputDecorator...cannot have an unbounded width」
Row(
children: [
const Icon(Icons.search),
TextField(),
],
)
輸出(已解決狀態):
// 將 TextField 包在 Expanded 中,將其寬度限制在 Row 的剩餘空間
Row(
children: [
const Icon(Icons.search),
Expanded(
child: TextField(),
),
],
)
修復 RenderFlex 溢出
輸入(錯誤狀態):
// 拋出「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.'),
],
)
輸出(已解決狀態):
// 將 Text 元件包在 Expanded 中,強制其在可用約束內換行
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.'),
),
],
)






