You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter中Position嵌套FractionallySizedBox时布局失效及报错问题

问题分析与解决

你遇到的Box Constraints forces an infinite width错误,核心原因是:

  • Positioned同时设置top:0和bottom:0时,会强制子组件高度填满Stack上下空间,此时子组件的约束是无限的;
  • FractionallySizedBox需要基于父级明确约束计算尺寸,无限约束下无法确定自身宽高,因此报错;
  • 主圆圈用FractionallySizedBox(widthFactor:1, heightFactor:1),但父级Stack没有明确尺寸约束,导致主圆圈大小不确定,小圆圈的比例计算失去参照。

修正方案

方法1:给主圆圈明确尺寸,直接计算小圆圈大小

让自定义组件接收尺寸参数,主圆圈用SizedBox固定大小,小圆圈基于该尺寸的20%设置宽高,再通过Positioned定位到右上角:

class CustomWidget extends StatelessWidget {
  final double size;
  const CustomWidget({Key? key, required this.size}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Stack(
      clipBehavior: Clip.none,
      alignment: Alignment.center,
      children: [
        // 主圆圈
        SizedBox(
          width: size,
          height: size,
          child: Container(
            decoration: const BoxDecoration(
              color: Colors.red,
              shape: BoxShape.circle,
            ),
          ),
        ),
        // 徽章小圆圈
        Positioned(
          top: -size * 0.1, // 向上偏移一半小圆圈高度,让一半露在外面
          right: -size * 0.1, // 向右偏移一半小圆圈宽度
          child: SizedBox(
            width: size * 0.2,
            height: size * 0.2,
            child: Container(
              decoration: const BoxDecoration(
                color: Colors.yellow,
                shape: BoxShape.circle,
              ),
            ),
          ),
        ),
      ],
    );
  }
}

方法2:用LayoutBuilder获取父级约束

如果希望组件自适应父级空间,可通过LayoutBuilder获取父级约束,再计算主圆圈和小圆圈的大小:

class CustomWidget extends StatelessWidget {
  const CustomWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        final size = constraints.biggest.shortestSide; // 取父级宽高中较小值,保证是圆形
        return Stack(
          clipBehavior: Clip.none,
          alignment: Alignment.center,
          children: [
            // 主圆圈
            SizedBox(
              width: size,
              height: size,
              child: Container(
                decoration: const BoxDecoration(
                  color: Colors.red,
                  shape: BoxShape.circle,
                ),
              ),
            ),
            // 徽章小圆圈
            Positioned(
              top: -size * 0.1,
              right: -size * 0.1,
              child: SizedBox(
                width: size * 0.2,
                height: size * 0.2,
                child: Container(
                  decoration: const BoxDecoration(
                    color: Colors.yellow,
                    shape: BoxShape.circle,
                  ),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
}

关键改动说明

  1. 去掉FractionallySizedBox,改用SizedBox直接基于主圆圈尺寸计算小圆圈大小,避免无限约束问题;
  2. 通过Positioned的top和right偏移,让小圆圈一半露在主圆圈外,符合Badge常见样式;
  3. 给主圆圈明确尺寸约束,确保小圆圈的比例计算有参照。

内容的提问来源于stack exchange,提问作者user22362195

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:32:50