skip to Main Content

we need to locate 8 buttons in a shape of half circle with equal distance from another button like shown in picture below:

(https://phpout.com/wp-content/uploads/2023/05/F0R75.png)

  • we tried to use positioned widgets but it didnt work.

enter image description here

2

Answers


  1. Try this:

    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'),
                  ),
                ),
            ],
          ),
        );
      }
    }
    

    Now you can use the HalfCircleButton widget as follows:

    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],
                  ),
                ),
            ],
          ),
        );
      }
    }
    

    output

    Login or Signup to reply.
  2. This is what my solution looks like:
    SemicircleLayout

    I hope this works for you.

    Here is the code for this layout:

    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(),
          ],
        );
      }
    }
    

    To use this widget you give it array of children, center widget and radius.

    Example of usage:

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

    // RoundButton() is a custom Widget I used for buttons

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search