颤振布局问题:堆栈 z 顺序不起作用
Posted
技术标签:
【中文标题】颤振布局问题:堆栈 z 顺序不起作用【英文标题】:Flutter layout issue: stack z-order not working 【发布时间】:2020-01-29 15:04:23 【问题描述】:栈子布局的 z-order 与我的预期不同。
我在堆栈中有 4 个带有键的小部件:0、1、2、3。我尝试更改它们的 z 顺序并重建堆栈小部件。这是我的代码:
class TestBringToFrontPage extends StatefulWidget
TestBringToFrontPage(Key key) : super(key: key);
@override
State<TestBringToFrontPage> createState() => TestBringToFrontState();
class TestBringToFrontState extends State<TestBringToFrontPage>
List<Widget> _widgets = [];
@override
Widget build(BuildContext context)
return Stack(children: <Widget>[
..._widgets,
Positioned(
bottom: 0,
right: 0,
child: RaisedButton(
child: Text(
"click",
style: TextStyle(color: Colors.white),
),
onPressed: ()
setState(()
_swap(0, 2);
_swap(1, 3);
print("$_widgets");
);
,
)),
]);
@override
void initState()
super.initState();
const double start = 100;
const double size = 100;
_widgets = <Widget>[
_buildWidget(key: const Key("0"), color: Colors.blue, offset: const Offset(start, start), size: const Size(size, size)),
_buildWidget(key: const Key("1"), color: Colors.green, offset: const Offset(start + size / 2, start), size: const Size(size, size)),
_buildWidget(key: const Key("2"), color: Colors.yellow, offset: const Offset(start, start + size / 2), size: const Size(size, size)),
_buildWidget(key: const Key("3"), color: Colors.red, offset: const Offset(start + size / 2, start + size / 2), size: const Size(size, size)),
];
Widget _buildWidget(Key key, Color color, Offset offset, Size size)
final label = (key as ValueKey<String>)?.value;
return Positioned(
key: key,
left: 0,
top: 0,
child: Container(
transform: Matrix4.identity()..translate(offset.dx, offset.dy, 0),
width: size.width,
height: size.height,
decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 1.0), color: color),
child: Text(
label,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
decoration: TextDecoration.none,
fontSize: 15.0,
),
),
));
void _swap(int x, int y)
final w = _widgets[x];
_widgets[x] = _widgets[y];
_widgets[y] = w;
在开始时,堆栈子级按 z 顺序排列(从下到上):0,1,2,3。屏幕显示: Starting screen state image
通过单击按钮,我希望堆栈子级以新的 z 顺序排列:2,3,0,1。屏幕应显示: Expected screen state image
但与预期不同,屏幕显示: Actual screen state image.
点击按钮时的控制台日志:“[Positioned-[](left: 0.0, top: 0.0), Positioned-[](left: 0.0, top: 0.0), Positioned-[](left: 0.0, top: 0.0), Positioned-[](left: 0.0, top: 0.0)]"
在 Flutter 检查器窗口中,堆栈子项的顺序正确:2,3,0,1。但是堆栈呈现错误。
你知道我错在哪里还是颤振布局问题? 提前谢谢你,
【问题讨论】:
【参考方案1】:在玩了一会儿你的代码之后,我发现每个块上的 Key
都处于某种状态,这会在 setState
期间弄乱它们的顺序。移除钥匙会给我你所期望的行为。我不知道为什么会发生这种情况,但至少现在你有一个解决方案,如果你的目标不需要密钥。
不管他们是不是,如果我是你,我会提交一个错误报告,因为我很确定这种行为不是故意的。
这是我使用的有效代码(我清理了一点,所以它不会覆盖initState
):
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
title: 'Flutter Demo',
home: TestBringToFrontPage(),
);
class TestBringToFrontPage extends StatefulWidget
TestBringToFrontPage(Key key) : super(key: key);
@override
State<TestBringToFrontPage> createState() => TestBringToFrontState();
class TestBringToFrontState extends State<TestBringToFrontPage>
static const start = 50.0;
static const size = 250.0;
final _widgets = <Widget>[
_buildWidget(label: "0", color: Colors.blue, offset: const Offset(start, start), size: const Size(size, size)),
_buildWidget(label: "1", color: Colors.green, offset: const Offset(start + size / 2, start), size: const Size(size, size)),
_buildWidget(label: "2", color: Colors.yellow, offset: const Offset(start, start + size / 2), size: const Size(size, size)),
_buildWidget(label: "3", color: Colors.red, offset: const Offset(start + size / 2, start + size / 2), size: const Size(size, size)),
];
@override
Widget build(BuildContext context)
return Stack(children: <Widget>[
..._widgets,
Positioned(
bottom: 0,
right: 0,
child: RaisedButton(
child: Text(
"click",
style: TextStyle(color: Colors.white),
),
onPressed: ()
setState(()
_swap(0, 2);
_swap(1, 3);
print("$_widgets");
);
,
)),
]);
static Widget _buildWidget(String label, Color color, Offset offset, Size size)
return Positioned(
left: 0,
top: 0,
child: Container(
transform: Matrix4.identity()..translate(offset.dx, offset.dy, 0),
width: size.width,
height: size.height,
decoration: BoxDecoration(border: Border.all(color: Colors.black, width: 1.0), color: color),
child: Text(
label,
textAlign: TextAlign.left,
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w700,
decoration: TextDecoration.none,
fontSize: 30.0,
),
),
));
void _swap(int x, int y)
final w = _widgets[x];
_widgets[x] = _widgets[y];
_widgets[y] = w;
【讨论】:
谢谢。我在这里提出了一个问题:github.com/flutter/flutter/issues/41706 当您删除键时,我猜小部件的旧元素被卸载(并删除),新元素被创建然后分配给小部件。通过这种方式,以某种方式更新了绘画的元素顺序。以上是关于颤振布局问题:堆栈 z 顺序不起作用的主要内容,如果未能解决你的问题,请参考以下文章