【问题标题】:Flutter's Navigation 2.0 doesn't update the UIFlutter 的 Navigation 2.0 没有更新 UI
【发布时间】:2021-11-03 21:06:06
【问题描述】:

我正在尝试了解如何使用 Flutter 的声明式导航系统。我想创建一个简单的应用程序,它将无限地添加/删除到堆栈的路由。就像,“屏幕 N”有两个按钮:首先将其从堆栈中弹出,然后将“屏幕 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

【问题讨论】:

    标签: flutter flutter-navigation


    【解决方案1】:

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

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

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

    【讨论】:

      【解决方案2】:

      我不知道为什么,但问题已通过替换解决

      pages: _pages,
      

      pages: _pages.toList(),
      

      pages: [..._pages],
      

      虽然两种变体都能正确编译。

      【讨论】:

      • 你知道当你调用setState()时,它会通知框架一个对象的内部状态已经改变。但是,从列表中添加或删除项目不会更改对该列表的引用。它只是修改了它的项目,而您的小部件并没有意识到这一点。通过使用toList()或其他方式,实际上传递了一个新创建的列表,其中包含_pages的修改项。
      猜你喜欢
      • 1970-01-01
      • 2020-09-04
      • 1970-01-01
      • 2020-10-15
      • 2021-01-19
      • 2021-06-18
      • 2019-06-19
      • 1970-01-01
      • 2021-12-17
      相关资源
      最近更新 更多