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

Flutter实现大圆形容器上12个等距小圆形的响应式布局

实现方案

核心思路

通过三角函数计算坐标结合Stack+Positioned组件,实现小圆在大圆圆周上的均匀分布;利用LayoutBuilder监听父容器尺寸变化,确保布局随大圆形缩放自动调整。

关键步骤

  1. 确定大圆形半径:取父容器宽高最小值的一半,保证大圆形始终为正圆。
  2. 计算小圆位置:
    • 12个小圆间隔30°,遍历角度从0°到359°,步长为30°。
    • 将角度转换为弧度后,用cos/sin计算小圆中心相对于大圆形中心的偏移量:
      final dx = bigRadius * cos(angleRad);
      final dy = bigRadius * sin(angleRad);
      
  3. 定位小圆:通过Positioned组件,根据偏移量设置left和top,确保小圆中心精准落在大圆周上。

完整代码示例

import 'dart:math';
import 'package:flutter/material.dart';

class CircularLayout extends StatelessWidget {
  final int smallCircleCount = 12;
  final double smallCircleRadius = 15;

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        // 计算大圆形半径(取宽高最小值的一半)
        final bigRadius = min(constraints.maxWidth, constraints.maxHeight) / 2;
        final centerX = constraints.maxWidth / 2;
        final centerY = constraints.maxHeight / 2;

        return Stack(
          alignment: Alignment.center,
          children: [
            // 大圆形容器
            Container(
              width: bigRadius * 2,
              height: bigRadius * 2,
              decoration: BoxDecoration(
                color: Colors.grey[200],
                shape: BoxShape.circle,
              ),
            ),
            // 生成12个均匀分布的小圆
            ...List.generate(smallCircleCount, (index) {
              final angle = index * 30; // 每个小圆间隔30度
              final angleRad = angle * pi / 180; // 转换为弧度
              // 计算小圆中心相对于大圆形中心的偏移
              final dx = bigRadius * cos(angleRad);
              final dy = bigRadius * sin(angleRad);
              // 计算小圆的定位坐标(使中心落在大圆周上)
              final left = centerX + dx - smallCircleRadius;
              final top = centerY + dy - smallCircleRadius;

              return Positioned(
                left: left,
                top: top,
                child: Container(
                  width: smallCircleRadius * 2,
                  height: smallCircleRadius * 2,
                  decoration: BoxDecoration(
                    color: Colors.blue,
                    shape: BoxShape.circle,
                  ),
                ),
              );
            }),
          ],
        );
      },
    );
  }
}

// 使用示例
void main() {
  runApp(MaterialApp(
    home: Scaffold(
      body: Center(
        // 用SizedBox模拟响应式缩放,实际可替换为任意父容器
        child: SizedBox(
          width: 300,
          height: 300,
          child: CircularLayout(),
        ),
      ),
    ),
  ));
}

补充说明

  • 响应式适配:LayoutBuilder会自动监听父容器尺寸变化,每次尺寸更新时重新计算所有小圆位置,确保始终贴合大圆周。
  • 参数定制:可修改smallCircleCount(小圆数量)、smallCircleRadius(小圆半径)调整布局效果。
  • 角度逻辑:按360°/12=30°的间隔计算角度,保证小圆均匀分布。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 11:56:13