Flutter Spacer引发的The ParentDataWidget Expanded(flex: 1) 惨案

问题描述

在flutter控制台中遇到如下报错:

bash 复制代码
The following assertion was thrown while applying parent data.:
Incorrect use of ParentDataWidget.

The ParentDataWidget Expanded(flex: 1) wants to apply ParentData of type FlexParentData to a RenderObject, which has been set up to accept ParentData of incompatible type StackParentData.

Usually, this means that the Expanded widget has the wrong ancestor RenderObjectWidget. Typically, Expanded widgets are placed directly inside Flex widgets.
The offending Expanded is currently placed inside a Stack widget.

The ownership chain for the RenderObject that received the incompatible parent data was:
  SizedBox.shrink ← Expanded ← Spacer ← Stack ← ConstrainedBox ← Padding ← Container ← Listener ← _GestureSemantics ← RawGestureDetector ← ⋯

问题分析

网上千篇一律的错误信息,都说是Expanded和Stack的关系问题。

但是排查代码中却没有任何地方使用到Expanded,而且由于报错没有指出在哪个页面,所以,问题一时间僵住了。

最后,通过一个一个注释代码块,确定问题大致代码块,最后按照SizedBox.shrink ← Expanded ← Spacer ← Stack ← ConstrainedBox ← Padding ← Container ← Listener ← _GestureSemantics ← RawGestureDetector ← ⋯顺序

一个一个在页面中排查,排查到Spacer,点击进去查看实现,Spacer的会当场build一个Expanded。

Spacer的源码如下:

dart 复制代码
class Spacer extends StatelessWidget {
  /// Creates a flexible space to insert into a [Flexible] widget.
  ///
  /// The [flex] parameter may not be null or less than one.
  const Spacer({super.key, this.flex = 1})
    : assert(flex > 0);

  /// The flex factor to use in determining how much space to take up.
  ///
  /// The amount of space the [Spacer] can occupy in the main axis is determined
  /// by dividing the free space proportionately, after placing the inflexible
  /// children, according to the flex factors of the flexible children.
  ///
  /// Defaults to one.
  final int flex;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: flex,
      child: const SizedBox.shrink(),
    );
  }
}

可以看到Spacer的build方法中,直接返回了一个Expanded,而Expanded的child是SizedBox.shrink()。这就是问题的根源。

解决方案

找到问题所在的页面,将Expanded和Spacer的关系注释掉,或者将Expanded的child改为Container,或者将Expanded的child改为Container()。

总结

不仅 Expanded 的使用限制在Flex/Row/Column中,Spacer 也有一样的限制。

相关推荐
Dev7z13 小时前
基于晶体塑性理论的FCC单晶本构模型数值实现与验证(硕士级别)
前端
早點睡39013 小时前
Flutter for Harmony 跨平台开发实战:鸿蒙与音乐律动艺术、FFT 频谱能量场:正弦函数的叠加艺术
flutter·华为·harmonyos
2601_9495936513 小时前
Flutter for Harmony 跨平台开发实战:德劳内三角剖分——点集连接的几何美学
flutter
前端嘣擦擦13 小时前
避坑笔记:Chrome 144+ SVG 事件失效问题
前端·javascript·chrome·笔记·svg2
秋天的一阵风13 小时前
🧠 空数组的迷惑行为:为什么 every 为真,some 为假?
前端·javascript·面试
渔舟唱晚@13 小时前
React 19 核心 Hooks 深度解析
前端·react.js·前端框架
Mintopia13 小时前
AI 开发还是 AI 辅助开发?——我近月的实践感受与技术建议
前端
lili-felicity13 小时前
基础入门 Flutter for OpenHarmony:三方库实战 flutter_lifecycle_detector 生命周期检测详解
flutter
2601_9495936513 小时前
Flutter for Harmony 跨平台开发实战:双曲几何与庞加莱圆盘——非欧空间的视觉映射
flutter
Mintopia13 小时前
下面列出若干真实世界和典型的成功实施 AI 开发(即 AI 作为产品或业务核心驱动力)案例
前端