gpt4 book ai didi

flutter - 不确定数量的 child 的堆栈对齐

转载 作者:IT王子 更新时间:2023-10-29 06:56:05 24 4
gpt4 key购买 nike

我正在 flutter 中构建一个应用程序,我正在做的部分工作是从服务器获取操作列表,然后为每个操作构建按钮。我试图在一个圆圈中显示按钮并生成一个凸起按钮小部件列表。然后我尝试使用 Stack 将此列表布置成一个圆圈,但是当我不知道我将拥有多少个对象(我知道它将在一个范围约为 3-15)。

这是我的堆栈的构建方法。假设所有方法、列表和变量都被正确定义并且有效。我只关心对齐

@override
Widget build(BuildContext context) {

List<Widget> actions = [];
for(var action in widget.actionsList){
actions.add(RaisedButton(
onPressed: () => _handleAction(action[0]),
shape: CircleBorder(),
child: Text(action[1] + ': ' + action[2]),
));
}

return Scaffold(
body: Center(
child: Stack(
children: actions,
alignment: //HELP,
),
),
);
}

如果您对如何进行对齐或制作一圈按钮的其他方法有任何想法,请告诉我。我真的很想做一个圆圈,但我并不认为它不可能(我对此表示怀疑)或 super 复杂。

谢谢!

最佳答案

这是我的做法。

TL;DR;

  final actionsList = [
"one",
"two",
"three",
"four",
"five",
];

@override
Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: layedOutButtons(
centerOfCircle:
Offset(constraints.maxWidth, constraints.maxHeight) / 2,
circleRadius: 100,
),
),
),
);
}

Offset getCoordinateFromAngle({double radius, double angle}) => Offset(
radius * sin(angle),
radius * cos(angle),
);

List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
var buttonRadius = 25.0;
var dispatchAngle = pi * 2 / actionsList.length;

List<Widget> widgets = [];
var i = 0;

for (var action in actionsList) {
var position = getCoordinateFromAngle(
radius: circleRadius,
angle: dispatchAngle * i++,
);
widgets.add(
Positioned(
top: centerOfCircle.dy - position.dy - buttonRadius,
left: centerOfCircle.dx + position.dx - buttonRadius,
width: buttonRadius * 2,
height: buttonRadius * 2,
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}

return widgets;
}

解释

如果你想在一个圆上发送多个小部件,你必须:

  1. 定义centerOfCircle,即圆心的位置。为此,我使用 LayoutBuilder 小部件获取布局的约束并确定 Stack 的中心 => (width/2, height/2)。
  2. 定义 circleRadius,该圆的半径(在我的示例中:100)

将这些数据提供给 layedOutButtons,它将使用 Positioned 小部件在圆上调度小部件。

  Widget build(BuildContext context) {
return Scaffold(
body: LayoutBuilder(
builder: (context, constraints) => Stack(
children: layedOutButtons(
centerOfCircle: Offset(constraints.maxWidth, constraints.maxHeight) / 2,
circleRadius: 100,
),
),
),
);
}

List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
List<Widget> widgets = [];

for (var action in actionsList) {
widgets.add(
Positioned(
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}

return widgets;
}

现在,您需要定义如何根据小部件的数量在圆圈上分配小部件。例如,如果有 2 个小部件,则以彼此 180° 的角度发送它们(意味着一个在圆的顶部,一个在底部。如果有 4 个,则以彼此 90° 的角度发送,等等。请注意,它表示为弧度(不是度数)。

var dispatchAngle = pi * 2 / actionsList.length;

然后您必须根据角度定义圆上点的坐标 (x, y)(参见 this)。

Offset getCoordinateFromAngle({double radius, double angle}) => Offset(
radius * sin(angle),
radius * cos(angle),
);

使用它来填充 Positioned 小部件的 topleft 属性。

  List<Widget> layedOutButtons({
Offset centerOfCircle,
double circleRadius,
}) {
var dispatchAngle = pi * 2 / actionsList.length;

List<Widget> widgets = [];
var i = 0;

for (var action in actionsList) {
var position = getCoordinateFromAngle(
radius: circleRadius,
angle: dispatchAngle * i++, //increment angle for each widget
);
widgets.add(
Positioned(
top: centerOfCircle.dy - position.dy, //something's wrong here
left: centerOfCircle.dx + position.dx, //something's wrong here
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),
);
}

return widgets;
}

现在一切都准备就绪了,除​​了有一个错位。这是因为小部件是基于其左上角定位的。我们想要优化定位,使其与我们的小部件的中心相匹配。

var buttonRadius = 25.0;

Positioned(
top: centerOfCircle.dy - position.dy - buttonRadius,
left: centerOfCircle.dx + position.dx - buttonRadius,
width: buttonRadius * 2,
height: buttonRadius * 2,
child: FloatingActionButton(
child: Text(action),
onPressed: () {},
),
),

关于flutter - 不确定数量的 child 的堆栈对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57194014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com