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

如何将8个按钮以半圆形状等距围绕另一按钮定位?Positioned widgets无效

Flutter 实现半圆分布的按钮布局(8个按钮+中心按钮)

直接用三角函数计算位置+Stack布局就能搞定,比手动写Positioned坐标精准且自适应,代码示例如下:

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

class SemiCircleButtonLayout extends StatelessWidget {
  const SemiCircleButtonLayout({super.key});

  @override
  Widget build(BuildContext context) {
    const int outerButtonCount = 8;
    const double centerToOuterDistance = 120; // 外层按钮到中心的距离
    const double centerBtnSize = 60;
    const double outerBtnSize = 50;

    return Scaffold(
      body: Center(
        child: LayoutBuilder(
          builder: (ctx, constraints) {
            final parentCenterX = constraints.maxWidth / 2;
            final parentCenterY = constraints.maxHeight / 2;

            return Stack(
              alignment: Alignment.center,
              children: [
                // 中心按钮
                Container(
                  width: centerBtnSize,
                  height: centerBtnSize,
                  decoration: const BoxDecoration(
                    color: Colors.blueAccent,
                    shape: BoxShape.circle,
                  ),
                  child: const Center(
                    child: Text(
                      "中心",
                      style: TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
                    ),
                  ),
                ),
                // 外层半圆按钮组
                ...List.generate(outerButtonCount, (index) {
                  // 计算当前按钮的角度:半圆覆盖0到π弧度(0°到180°),均匀分配8个按钮
                  final angle = pi * index / (outerButtonCount - 1);
                  // 基于三角函数计算偏移量
                  final offsetX = centerToOuterDistance * cos(angle);
                  final offsetY = centerToOuterDistance * sin(angle);

                  return Positioned(
                    // 定位时减去按钮自身一半尺寸,保证按钮中心对准计算点
                    left: parentCenterX - outerBtnSize / 2 + offsetX,
                    top: parentCenterY - outerBtnSize / 2 - offsetY,
                    child: ElevatedButton(
                      style: ElevatedButton.styleFrom(
                        fixedSize: Size(outerBtnSize, outerBtnSize),
                        shape: const CircleBorder(),
                        backgroundColor: Colors.orange,
                      ),
                      onPressed: () {},
                      child: Text(
                        "${index + 1}",
                        style: const TextStyle(color: Colors.white),
                      ),
                    ),
                  );
                }),
              ],
            );
          },
        ),
      ),
    );
  }
}

关键说明

  • 用LayoutBuilder获取父容器尺寸,确保布局在不同屏幕上都能自适应居中
  • 通过三角函数cos/sin计算每个外层按钮的偏移量,保证所有按钮到中心的距离完全一致
  • 角度从0到π(180°)均匀分配,8个按钮的间隔角度为π/(8-1),避免两端按钮重叠
  • 定位时减去按钮自身半宽/半高,保证按钮的中心对准计算出的圆周点,布局更规整

如果需要下半圆/左半圆/右半圆,只需要调整角度的起始值和结束值即可,比如下半圆可以把角度范围改成π到2π。

内容的提问来源于stack exchange,提问作者מאי כהן

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 13:12:25