简体   繁体   English

Flutter 布局问题:堆栈 z 顺序不起作用

[英]Flutter layout issue: stack z-order not working

The z-order of stack children layout is not as my expectation.堆栈子布局的 z 顺序与我的预期不同。

I have 4 widgets in a stack with keys: 0,1,2,3.我在堆栈中有 4 个带有键的小部件:0、1、2、3。 I try to change their z-order and rebuild the stack widget.我尝试更改它们的 z 顺序并重建堆栈小部件。 Here is my code:这是我的代码:

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;
  }
}

At starting, stack children are laid out in z-order (from bottom to top): 0,1,2,3.开始时,堆栈子项按 z 顺序(从下到上)布置:0、1、2、3。 Screen shows: Starting screen state image屏幕显示:启动屏幕 state 图像

By clicking to the button, I expect the stack children are laid out in new z-order: 2,3,0,1.通过单击按钮,我希望堆栈子项以新的 z 顺序排列:2,3,0,1。 And screen should show: Expected screen state image屏幕应显示:预期屏幕 state 图像

But not as expected, screen shows: Actual screen state image.但与预期不同,屏幕显示:实际屏幕 state 图像。

Console log when clicking the button: "[Positioned-[<'2'>](left: 0.0, top: 0.0), Positioned-[<'3'>](left: 0.0, top: 0.0), Positioned-[<'0'>](left: 0.0, top: 0.0), Positioned-[<'1'>](left: 0.0, top: 0.0)]"单击按钮时的控制台日志:“[Positioned-[<'2'>](left: 0.0, top: 0.0), Positioned-[<'3'>](left: 0.0, top: 0.0), Positioned-[ <'0'>](左:0.0,上:0.0),定位-[<'1'>](左:0.0,上:0.0)]"

In Flutter inspectors window, the stack children are in correct order: 2,3,0,1.在 Flutter 检查员 window 中,堆栈子项的顺序正确:2,3,0,1。 But stack renders wrong.但是堆栈呈现错误。

Do you know where am I wrong or is it flutter layout issue?你知道我错在哪里还是 flutter 布局问题? Thank you in advance,先感谢您,

After playing around with your code for a little while, I've managed to figure out that the Key on each block is holding some state that messes their ordering up during setState .在玩了一会儿你的代码之后,我设法弄清楚每个块上的Key都持有一些 state ,这会在setState期间弄乱它们的顺序。 Removing the keys gives me the behaviour you're expecting.移除钥匙会给我你所期望的行为。 I don't know why this would be happening, but at least now you have a fix if the keys aren't needed for whatever your goal is.我不知道为什么会发生这种情况,但至少现在你有一个修复,如果你的目标不需要密钥。

Whether they are or not, I would file a bug report if I were you, because I'm pretty sure this behaviour isn't intended.不管他们是不是,如果我是你,我会提交一个错误报告,因为我很确定这种行为不是故意的。

Here's the code I used that works (I cleaned up a little bit of it so it doesn't override initState ):这是我使用的有效代码(我清理了一点,所以它不会覆盖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;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM