Home > database >  Position widgets in orbit around another widget in Flutter
Position widgets in orbit around another widget in Flutter

Time:08-17

anyone has an idea on how's the best way to position widgets in orbit AROUND another (circular) widget in flutter like this? Example

Thank you very much for any help you can give :D

CodePudding user response:

You can Use Stack Widget . For your Idea here is the Example:

import 'package:flutter/material.dart';

void main() {
  runApp(new MaterialApp(home: new ExampleWidget()));
}

class ExampleWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    Widget bigCircle = new Container(
      width: 300.0,
      height: 300.0,
      decoration: new BoxDecoration(
        color: Colors.orange,
        shape: BoxShape.circle,
      ),
    );

    return new Material(
      color: Colors.black,
      child: new Center(
        child: new Stack(
          children: <Widget>[
            bigCircle,
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.favorite_border),
              top: 10.0,
              left: 130.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.timer),
              top: 120.0,
              left: 10.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.place),
              top: 120.0,
              right: 10.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.local_pizza),
              top: 240.0,
              left: 130.0,
            ),
            new Positioned(
              child: new CircleButton(onTap: () => print("Cool"), iconData: Icons.satellite),
              top: 120.0,
              left: 130.0,
            ),
          ],
        ),
      ),
    );
  }
}

class CircleButton extends StatelessWidget {
  final GestureTapCallback onTap;
  final IconData iconData;

  const CircleButton({Key key, this.onTap, this.iconData}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    double size = 50.0;

    return new InkResponse(
      onTap: onTap,
      child: new Container(
        width: size,
        height: size,
        decoration: new BoxDecoration(
          color: Colors.white,
          shape: BoxShape.circle,
        ),
        child: new Icon(
          iconData,
          color: Colors.black,
        ),
      ),
    );
  }
}

CodePudding user response:

Not perfect but you can modify it.

class Avatar3xBtnMultiChildLayoutDelegate extends MultiChildLayoutDelegate {
  final double iconSize;
  Avatar3xBtnMultiChildLayoutDelegate(this.iconSize);

  @override
  void performLayout(Size size) {
    if (hasChild(0)) {
      layoutChild(
        0,
        BoxConstraints.loose(
            Size(size.width - iconSize, size.height - iconSize)),
      );
    }

    if (hasChild(1)) {
      layoutChild(
        1,
        BoxConstraints.loose(size),
      );
    }

    if (hasChild(2)) {
      layoutChild(
        2,
        BoxConstraints.loose(size),
      );
    }
    if (hasChild(3)) {
      layoutChild(
        3,
        BoxConstraints.loose(size),
      );
    }
    positionChild(0, Offset(iconSize / 2, iconSize / 2)); //circle
    positionChild(
      1,
      Offset(size.width - iconSize, size.height * .6 - iconSize / 2),
    ); //btn 1

    positionChild(
      2,
      Offset((size.width * .95) - iconSize, size.height * .7 - iconSize / 2),
    ); //btn 2
    positionChild(
      3,
      Offset((size.width * .9) - iconSize, size.height * .75),
    ); //btn 3
  }

  @override
  bool shouldRelayout(covariant Avatar3xBtnMultiChildLayoutDelegate oldDelegate) {
    return true;
  }
}

And using it


class CAPG extends StatefulWidget {
  const CAPG({Key? key}) : super(key: key);

  @override
  State<CAPG> createState() => _CAPGState();
}

class _CAPGState extends State<CAPG> {
  double value = 300;
  final iconSize = 24.0;
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          children: [
            Slider(
                value: value,
                max: 500,
                onChanged: (v) {
                  setState(() {
                    value = v;
                  });
                }),
            Container(
              width: value,
              height: value,
              clipBehavior: Clip.none,
              decoration: BoxDecoration(border: Border.all()),
              child: CustomMultiChildLayout(
                delegate: Avatar3xBtnMultiChildLayoutDelegate(iconSize),
                children: [
                  LayoutId(
                    id: 0,
                    child: Container(
                      width: value,
                      height: value,
                      decoration: BoxDecoration(
                        shape: BoxShape.circle,
                        border: Border.all(),
                        color: Colors.amber.withOpacity(.3),
                      ),
                    ),
                  ),
                  LayoutId(
                      id: 1,
                      child: Material(
                        color: Colors.purple,
                        shape: CircleBorder(),
                        child: Icon(Icons.one_k, size: iconSize),
                      )),
                  LayoutId(
                      id: 2,
                      child: Material(
                        color: Colors.purple,
                        shape: CircleBorder(),
                        child: Icon(Icons.two_k, size: iconSize),
                      )),
                  LayoutId(
                    id: 3,
                    child: Material(
                      color: Colors.purple,
                      shape: CircleBorder(),
                      child: Icon(Icons.three_k_outlined, size: iconSize),
                    ),
                  ),
                ],
              ),
            )
          ],
        ),
      ),
    );
  }
}

enter image description here

Note: Things can be improved, This is my first time using MultiChildLayoutDelegate. logic can be improved .

  • Related