为什么 SizedBox 的存在会移动 Stack 中的兄弟姐妹?
Why is the presence of a SizedBox moves the siblings in a Stack?
我正在为 Flutter 处理 Widget 定位的方式而苦恼。
上下文:我的目标是布置一个带有移动车辆和加油泵的动画场景;根据设备方向,我想缩放和定位观看者的眼睛(泵位置)在屏幕的中心,就像我在 iPhone 上使用原生 Swift 版本一样如下:
横向模式:
人像模式:
在尝试使用 Flutter 实现此目的时,我遇到了各种问题,其中一个是调试小部件的存在将其他小部件从同一堆栈中移出:
它以堆栈中的 SizedBox 为中心…
但没有它就不行了:
我的代码如下,可以在此处找到最小的 darted 版本:https://dartpad.dev/?id=ccd214b1efacb61b158f6f0c2092e809
Widget buildScene(Size size, /* double scale,*/ bool debug) {
final hill = Hill(size: size);
final punmpOffsetX = size.width / 4;
// == Build the scene
return Stack(clipBehavior: Clip.none, children: [
// == The whole scene debug materialisation
if (debug). => THIS IS WHAT I TOGGLE WHICH MOVES THE REST OF THE SCENE
SizedBox(
width: size.width,
height: size.height,
child: Container(
color: const Color(0x7ff67e22),
)),
// == Add the sky
...widget.clouds,
// == Add ground
hill,
// == The pump
Transform.translate(
offset: Offset(punmpOffsetX /*- 115 / 2*/, 120),
child: Container(
width: 150,
child: ScaleTransition(
scale: Tween<double>(begin: 3, end: 1).animate(
CurvedAnimation(
parent: _controller, curve: Curves.elasticOut)),
child: Pump(offset: Offset.zero, width: 150)))),
// == The animated vehicle
DrivingVehicle(hill: hill),
我终于找到了一个解决方案,它包括使用 Positioned() Widget 来绝对定位 Widget。 Transform.translate 向渲染流中的小部件当前位置添加平移,这就是为什么删除小部件会使其余小部件移动的原因。
代码变为:
// == Build the scene
return Stack(clipBehavior: Clip.none, children: [
// == The whole scene debug materialisation
if (debug)
Positioned(left: 0, top: 0, child: SizedBox(
width: size.width,
height: size.height,
child: Container(
color: const Color(0x7ff67e22),
))),
// == Add ground
Positioned(left: 0, top: 0, child: hill),
// == The pump
Positioned(left: punmpOffsetX, top: 120, child:
offset: Offset(punmpOffsetX /*- 115 / 2*/, 120),
child: Container(
width: 150,
child: ScaleTransition(
scale: Tween<double>(begin: 3, end: 1).animate(
CurvedAnimation(
parent: _controller, curve: Curves.elasticOut)),
child: Pump(offset: Offset.zero, width: 150)))),
// == The animated vehicle
Positioned(left: 0, top: 0, child: DrivingVehicle(hill: hill)),
我正在为 Flutter 处理 Widget 定位的方式而苦恼。
上下文:我的目标是布置一个带有移动车辆和加油泵的动画场景;根据设备方向,我想缩放和定位观看者的眼睛(泵位置)在屏幕的中心,就像我在 iPhone 上使用原生 Swift 版本一样如下:
横向模式:
人像模式:
在尝试使用 Flutter 实现此目的时,我遇到了各种问题,其中一个是调试小部件的存在将其他小部件从同一堆栈中移出:
它以堆栈中的 SizedBox 为中心…
但没有它就不行了:
我的代码如下,可以在此处找到最小的 darted 版本:https://dartpad.dev/?id=ccd214b1efacb61b158f6f0c2092e809
Widget buildScene(Size size, /* double scale,*/ bool debug) {
final hill = Hill(size: size);
final punmpOffsetX = size.width / 4;
// == Build the scene
return Stack(clipBehavior: Clip.none, children: [
// == The whole scene debug materialisation
if (debug). => THIS IS WHAT I TOGGLE WHICH MOVES THE REST OF THE SCENE
SizedBox(
width: size.width,
height: size.height,
child: Container(
color: const Color(0x7ff67e22),
)),
// == Add the sky
...widget.clouds,
// == Add ground
hill,
// == The pump
Transform.translate(
offset: Offset(punmpOffsetX /*- 115 / 2*/, 120),
child: Container(
width: 150,
child: ScaleTransition(
scale: Tween<double>(begin: 3, end: 1).animate(
CurvedAnimation(
parent: _controller, curve: Curves.elasticOut)),
child: Pump(offset: Offset.zero, width: 150)))),
// == The animated vehicle
DrivingVehicle(hill: hill),
我终于找到了一个解决方案,它包括使用 Positioned() Widget 来绝对定位 Widget。 Transform.translate 向渲染流中的小部件当前位置添加平移,这就是为什么删除小部件会使其余小部件移动的原因。
代码变为:
// == Build the scene
return Stack(clipBehavior: Clip.none, children: [
// == The whole scene debug materialisation
if (debug)
Positioned(left: 0, top: 0, child: SizedBox(
width: size.width,
height: size.height,
child: Container(
color: const Color(0x7ff67e22),
))),
// == Add ground
Positioned(left: 0, top: 0, child: hill),
// == The pump
Positioned(left: punmpOffsetX, top: 120, child:
offset: Offset(punmpOffsetX /*- 115 / 2*/, 120),
child: Container(
width: 150,
child: ScaleTransition(
scale: Tween<double>(begin: 3, end: 1).animate(
CurvedAnimation(
parent: _controller, curve: Curves.elasticOut)),
child: Pump(offset: Offset.zero, width: 150)))),
// == The animated vehicle
Positioned(left: 0, top: 0, child: DrivingVehicle(hill: hill)),