【问题标题】:Flutter layout issue: stack z-order not working颤振布局问题:堆栈 z 顺序不起作用
【发布时间】: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。但是堆栈呈现错误。

你知道我错在哪里还是颤振布局问题? 提前谢谢你,

【问题讨论】:

    标签: flutter flutter-layout


    【解决方案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 当您删除键时,我猜小部件的旧元素被卸载(并删除),新元素被创建然后分配给小部件。通过这种方式,以某种方式更新了绘画的元素顺序。
    猜你喜欢
    • 2022-10-17
    • 2019-05-25
    • 2019-04-21
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 2021-09-02
    • 2019-09-08
    • 2023-04-11
    相关资源
    最近更新 更多