在给定距离内定位按钮

问题描述 投票:0回答:2

我们需要将 8 个按钮定位成半圆形,与另一个按钮的距离相等,如下图所示:

(https://i.stack.imgur.com/F0R75.png)

  • 我们尝试使用定位小部件,但没有用。

enter image description here

flutter position distance circleci
2个回答
0
投票

试试这个:

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

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Half Circle Buttons'),
      ),
      body: HalfCircleButton(
        radius: 150, // Adjust the radius as needed
        buttons: [
          for (var i in [1, 2, 3, 4, 5, 6, 7, 8])
            Container(
              color: Colors.black,
              width: 50,
              alignment: Alignment.center,
              height: 30,
              child: InkWell(
                onTap: () {
                  // Button $i action
                },
                child: Text('$i'),
              ),
            ),
        ],
      ),
    );
  }
}

现在您可以按如下方式使用 HalfCircleButton 小部件:

class HalfCircleButton extends StatelessWidget {
  final double radius;
  final List<Widget> buttons;

  HalfCircleButton({required this.radius, required this.buttons});

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: MediaQuery.of(context).size.width,
      child: Stack(
        children: [
          for (int i = 0; i < buttons.length; i++)
            Positioned(
              top: -sin(i * pi / (buttons.length - 1)) * radius + radius,
              left: -cos(i * pi / (buttons.length - 1)) * radius + radius,
              child: Padding(
                padding: const EdgeInsets.all(8.0),
                child: buttons[i],
              ),
            ),
        ],
      ),
    );
  }
}


0
投票

这就是我的解决方案: SemicircleLayout

我希望这对你有用。

这是此布局的代码:

class SemicircleLayout extends StatelessWidget {
  final List<Widget> children;
  final double radius;
  final double startAngle;
  final double endAngle;
  final Widget? centerWidget;

  const SemicircleLayout({
    super.key,
    required this.children,
    required this.radius,
    required this.centerWidget,
    this.startAngle = -pi,
    this.endAngle = 0,
  });

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        if (centerWidget != null)
          Positioned(
            left: radius,
            top: radius,
            child: centerWidget!,
          ),
        ...children
            .asMap()
            .map((index, child) {
          final angleFraction = (index / (children.length - 1));
          final angle = startAngle + (endAngle - startAngle) * angleFraction;
          final offsetX = radius * cos(angle);
          final offsetY = radius * sin(angle);

          return MapEntry(
            index,
            Positioned(
              left: radius + offsetX,
              top: radius + offsetY,
              child: Transform.rotate(
                angle: angle,
                child: child,
              ),
            ),
          );
        })
            .values
            .toList(),
      ],
    );
  }
}

要使用这个小部件,你给它一个孩子数组,中心小部件和半径。

使用示例:

SemicircleLayout(
   radius: 150.0,
   centerWidget: RoundButton(),
   children: [
      RoundButton(),
      RoundButton(),
      RoundButton(),
      RoundButton(),
      RoundButton(),
      RoundButton(),
      RoundButton(),
      RoundButton(),
   ],
)

// RoundButton() 是我用于按钮的自定义小部件

© www.soinside.com 2019 - 2024. All rights reserved.