anyone has an idea on how's the best way to position widgets in orbit AROUND another (circular) widget in flutter like this?
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),
),
),
],
),
)
],
),
),
);
}
}
Note: Things can be improved, This is my first time using MultiChildLayoutDelegate
. logic can be improved .