Flutter 的 Navigation 2.0 没有更新 UI

Flutter's Navigation 2.0 doesn't update the UI

我正在尝试了解如何使用 Flutter 的声明式导航系统。我想创建一个简单的应用程序,它将无限地添加/删除到堆栈的路由。比如,“Screen N”有两个按钮:首先将它从堆栈中弹出,然后将“Screen N+1”添加到堆栈中。所以,我制作了一个有状态的小部件来保存导航器状态 (pages):

class _MyAppState extends State<MyApp> {
  final List<Page> _pages = <Page>[];

  @override
  void initState() {
    super.initState();
    _dive(0);
  }

  @override
  Widget build(BuildContext context) {
    print(_pages);
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Navigator(
        pages: _pages,
        onPopPage: (route, result) {
          route.didPop(result);
          return true;
        },
      ),
    );
  }

  void _arise() {
    setState(() {
      print("Arise!");
      _pages.removeLast();
    });
  }

  void _dive(int value) {
    setState(() {
      print("Dive!");
      _pages.add(
        MaterialPage(
          key: ValueKey(value),
          child: DiveRoute(
            value,
            _arise,
            _dive,
          ),
        ),
      );
    });
  }
}

这是一个“第 N 屏”小部件:

class DiveRoute extends StatelessWidget {
  final int _value;
  final void Function() _arise;
  final void Function(int) _dive;

  const DiveRoute(
    this._value,
    this._arise,
    this._dive, {
    Key? key,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Dive"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text("$_value"),
            ElevatedButton(
              onPressed: () => _arise(),
              child: Text("Up"),
            ),
            ElevatedButton(
              onPressed: () => _dive(_value + 1),
              child: Text("Down"),
            ),
          ],
        ),
      ),
    );
  }
}

该应用程序正确绘制了第一个屏幕 (0),但单击按钮不会更新 UI,尽管 prints 在控制台中可见并且我看到列表页面增长和收缩。

Here is a DartPad

我不确定为什么,但是通过更换

解决了这个问题
pages: _pages,

pages: _pages.toList(),

pages: [..._pages],

尽管两种变体都可以正确编译。

他们使用 != 来比较 pages 变量(navigator.dart):

if (oldWidget.pages != widget.pages && !restorePending) {

因此每次更新 pages 变量时都需要提供一个新实例。