首页 > 解决方案 > Flutter 的 Navigation 2.0 没有更新 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它们在控制台中可见,并且我看到页面列表如何增长和缩小。

这是一个飞镖垫

标签: flutterflutter-navigation

解决方案


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

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

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


推荐阅读