mcpField
F
flutter-fix-layout-issues

flutter-fix-layout-issues

github.com/dhruvanbhalara开发3059 次安装9 周前更新
代码仓库

关于 flutter-fix-layout-issues

flutter-fix-layout-issues 是帮助开发者排查和修复 Flutter 布局问题的 Skill。它将常见错误信息对应到约束原因和修复模式,并提供按步骤验证的工作流。

主要功能

  1. 01按错误特征定位布局原因
  2. 02解释 Flutter 约束协商模型
  3. 03提供 Expanded 等修复模式
  4. 04区分首要错误与级联错误
  5. 05包含常见布局问题示例

适用场景

  1. 01修复 Column 中滚动视图高度无界问题
  2. 02处理 Row 中 TextField 宽度无界问题
  3. 03解决 RenderFlex 溢出
  4. 04纠正 ParentData widget 的位置

安装

复制下面的命令,在终端中运行。

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

安装后在 Claude Code 中输入/flutter-fix-layout-issues确认已加载。

详细介绍

目录

约束模型

Flutter 布局遵循严格的协商规则:

约束向下传递。尺寸向上返回。父级设置位置。

  1. 父级组件将约束(最小/最大宽度和高度)传递给子级。
  2. 子级在这些约束范围内确定自己的尺寸。
  3. 父级决定子级的位置。

当这种协商失败时,就会发生布局错误(通常是因为父级提供了无界约束,而子级试图无限扩展)。

错误特征目录

错误消息根本原因快速修复
Vertical viewport was given unbounded height可滚动组件(ListView、GridView)位于垂直方向不受约束的父级(Column)中使用 Expanded 或 SizedBox(height: ...) 包裹
An InputDecorator...cannot have an unbounded widthTextField 位于水平方向不受约束的父级(Row)中使用 Expanded 包裹
A RenderFlex overflowed by X pixels子级超出父级分配的约束使用 Expanded、Flexible 包裹,或使用 overflow: TextOverflow.ellipsis
Incorrect use of ParentData widgetExpanded 位于 Flex 外部,或 Positioned 位于 Stack 外部将组件移为正确父级的直接子级
RenderBox was not laid out级联错误:查看堆栈跟踪中的上游信息修复它之前出现的主要约束错误

规则:始终先修复堆栈跟踪中的第一个错误。RenderBox was not laid out 几乎总是级联产生的副作用。

解决模式

决策树
Error detected
├── Contains "unbounded height"?
│   └── Wrap scrollable child in Expanded or SizedBox
├── Contains "unbounded width"?
│   └── Wrap TextField/InputDecorator in Expanded
├── Contains "RenderFlex overflowed"?
│   ├── Text overflow?
│   │   └── Add overflow: TextOverflow.ellipsis + Expanded wrapper
│   └── Widget overflow?
│       └── Wrap in Expanded or Flexible
├── Contains "ParentData"?
│   └── Ensure Expanded is direct child of Row/Column/Flex
│       Ensure Positioned is direct child of Stack
└── Contains "RenderBox was not laid out"?
    └── IGNORE: fix the error above this one
Expanded、Flexible 与 SizedBox 的区别
组件行为适用场景
Expanded强制子级填满所有剩余空间子级应拉伸填满空间
Flexible允许子级小于剩余空间子级有自然尺寸,但不应溢出
SizedBox提供绝对固定的约束你知道所需的确切尺寸
ConstrainedBox设置最小/最大约束你需要有界的灵活性

工作流:修复布局问题

任务进度
  • 步骤 1:以调试模式运行应用:在控制台中捕获确切的异常。
  • 步骤 2:识别主要错误消息(忽略级联错误 RenderBox was not laid out)。
  • 步骤 3:将错误与上面的错误特征目录进行匹配。
  • 步骤 4:应用相应的修复:
    • 如果是 unbounded height → 使用 Expanded 或 SizedBox 包裹可滚动组件
    • 如果是 unbounded width → 使用 Expanded 包裹输入组件
    • 如果是 RenderFlex overflowed → 使用 Expanded 或 Flexible 包裹
    • 如果是 ParentData → 重构组件树
  • 步骤 5:热重载 → 验证错误已解决。
  • 步骤 6:如果出现新的布局错误 → 从步骤 2 开始重复。

示例

修复无界高度问题(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')),
      ],
    ),
  ],
)

修复后(已解决):

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(),
  ],
)

修复后(已解决):

Row(
  children: [
    const Icon(Icons.search),
    Expanded(
      child: TextField(),
    ),
  ],
)
修复 RenderFlex 溢出问题(Row 中的 Text)

修复前(抛出 A RenderFlex overflowed by X pixels on the right):

Row(
  children: [
    const Icon(Icons.info),
    Text('This is a very long text that will overflow the screen width'),
  ],
)

修复后(已解决):

Row(
  children: [
    const Icon(Icons.info),
    Expanded(
      child: Text(
        'This is a very long text that will overflow the screen width',
        overflow: TextOverflow.ellipsis,
      ),
    ),
  ],
)
修复 ParentData 使用错误

修复前(抛出 Incorrect use of ParentData widget):

// Expanded must be a DIRECT child of Row/Column/Flex
Container(
  child: Expanded(  // WRONG: Expanded not inside a Flex
    child: Text('Hello'),
  ),
)

修复后(已解决):

Row(
  children: [
    Expanded(  // OK: Direct child of Row (a Flex widget)
      child: Text('Hello'),
    ),
  ],
)

评论

支持 Markdown