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

如何在Flutter中创建响应式自定义Widget?

实现带嵌套内容的双圆形容器布局方案

核心思路

要实现两个可嵌套内容的响应式圆形容器,关键要解决两个问题:保证容器是正圆形(宽高必须相等),让布局适配不同屏幕尺寸。以下提供两种常见场景的实现方案:


场景1:并排双圆形(横向/纵向排列)

适合两个圆形需要并排展示的情况,用Row/Column配合Expanded+AspectRatio实现响应式自适应:

class DoubleCirclesRow extends StatelessWidget {
  final Widget leftCircleChild;
  final Widget rightCircleChild;

  const DoubleCirclesRow({
    super.key,
    required this.leftCircleChild,
    required this.rightCircleChild,
  });

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16),
      child: Row(
        children: [
          // 左侧圆形
          Expanded(
            child: AspectRatio(
              aspectRatio: 1, // 强制宽高1:1,确保是圆形
              child: Container(
                decoration: const BoxDecoration(
                  color: Colors.lightBlue,
                  shape: BoxShape.circle,
                ),
                child: Center(child: leftCircleChild), // 嵌套自定义内容
              ),
            ),
          ),
          const SizedBox(width: 20), // 圆形间距
          // 右侧圆形
          Expanded(
            child: AspectRatio(
              aspectRatio: 1,
              child: Container(
                decoration: const BoxDecoration(
                  color: Colors.orange,
                  shape: BoxShape.circle,
                ),
                child: Center(child: rightCircleChild),
              ),
            ),
          ),
        ],
      ),
    );
  }
}

使用示例:

DoubleCirclesRow(
  leftCircleChild: const Text("圆1", style: TextStyle(color: Colors.white, fontSize: 20)),
  rightCircleChild: const Icon(Icons.star, color: Colors.white, size: 40),
)

场景2:重叠双圆形(分层展示)

如果需要两个圆形重叠,用Stack+Positioned控制位置,结合MediaQuery实现响应式大小:

class OverlappingCircles extends StatelessWidget {
  final Widget backgroundCircleChild;
  final Widget foregroundCircleChild;

  const OverlappingCircles({
    super.key,
    required this.backgroundCircleChild,
    required this.foregroundCircleChild,
  });

  @override
  Widget build(BuildContext context) {
    final screenWidth = MediaQuery.of(context).size.width;
    final bigCircleSize = screenWidth * 0.7;
    final smallCircleSize = screenWidth * 0.4;

    return SizedBox(
      width: bigCircleSize,
      height: bigCircleSize,
      child: Stack(
        alignment: Alignment.center,
        children: [
          // 背景大圆形
          Container(
            width: bigCircleSize,
            height: bigCircleSize,
            decoration: const BoxDecoration(
              color: Colors.blueAccent,
              shape: BoxShape.circle,
            ),
            child: Center(child: backgroundCircleChild),
          ),
          // 前景小圆形(偏移定位)
          Positioned(
            bottom: 10,
            right: 10,
            child: Container(
              width: smallCircleSize,
              height: smallCircleSize,
              decoration: const BoxDecoration(
                color: Colors.orangeAccent,
                shape: BoxShape.circle,
              ),
              child: Center(child: foregroundCircleChild),
            ),
          ),
        ],
      ),
    );
  }
}

关键注意点

  1. 圆形的本质:必须保证容器宽高相等,AspectRatio(ratio:1)是最灵活的方式,无需硬编码尺寸。
  2. 响应式适配:用Expanded让圆形占满父布局可用空间,或用MediaQuery基于屏幕尺寸动态计算大小。
  3. Stack失败排查:如果之前用Stack没成功,大概率是没给Stack设置明确的宽高,或子组件的尺寸/定位没调整好。给Stack套一个SizedBox指定范围,再用Positioned精准控制子圆形的位置即可。

内容的提问来源于stack exchange,提问作者Ebubekir Alp Elvan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 13:30:11