首页 > 解决方案 > 为什么使用路由时 ChangeNotifierProvider 会从 Widget Tree 中消失?

问题描述

我无法理解这一点:当ChangeNotifierProvider小部件位于小部件树中的小部件下方时,当我使用该方法转到下一个屏幕MaterialApp时,它会从小部件树中消失。Navigator.of(context).pushReplacement但是,当ChangeNotifierProvider小部件高于MaterialApp小部件树中的那个时,它会停留在小部件树中。

下面是一个简单的例子。

ChangeNotifierProvider消失的小部件示例:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp( <= DIFFERENCE HERE
        title: 'Flutter Demo',
        home: ChangeNotifierProvider(
            create: (context) => ToiletsListModel(), child: SplashWidget()));
  }
}

class SplashWidget extends StatefulWidget {
  SplashWidget();

  @override
  State<SplashWidget> createState() => SplashWidgetState();
}

class SplashWidgetState extends State<SplashWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ElevatedButton(
        child: Text("press"),
        onPressed: goNext,
      ),
    );
  }

  goNext() async {
    await Future.delayed(Duration(seconds: 3));
    if (mounted) {
      Navigator.of(context).pushReplacement(
          MaterialPageRoute(builder: (BuildContext context) => HomeScreen()));
    }
  }

  @override
  void initState() {
    super.initState();
    [1, 2, 3, 4, 5].forEach((t) {
      Provider.of<MyModel>(context, listen: false).mylist.add(t);
    });
    print(Provider.of<MyModel>(context, listen: false).mylist);
  }
}

小部件树:

小部件树 1

ChangeNotifierProvider保持示例的小部件:

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider( <= DIFFERENCE HERE
        create: (context) => ToiletsListModel(),
        child: MaterialApp(title: 'Flutter Demo', home: SplashWidget()));
  }
}

class SplashWidget extends StatefulWidget {
  SplashWidget();

  @override
  State<SplashWidget> createState() => SplashWidgetState();
}

class SplashWidgetState extends State<SplashWidget> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ElevatedButton(
        child: Text("press"),
        onPressed: goNext,
      ),
    );
  }

  goNext() async {
    await Future.delayed(Duration(seconds: 3));
    if (mounted) {
      Navigator.of(context).pushReplacement(
          MaterialPageRoute(builder: (BuildContext context) => HomeScreen()));
    }
  }

  @override
  void initState() {
    super.initState();
    [1, 2, 3, 4, 5].forEach((t) {
      Provider.of<MyModel>(context, listen: false).mylist.add(t);
    });
    print(Provider.of<MyModel>(context, listen: false).mylist);
  }
} 

小部件树:

小部件树 2

这让我发疯,我找不到任何答案。我想这pushReplacement()对小部件树有什么作用或者ChangeNotifierProvider不是持久的(尽管我在文档中没有看到,我什至不确定这是否可能)。另外,我读到使用ChangeNotifierProvider上面的MaterialApp不是一个好主意,但我不知道为什么。

谢谢你的帮助。

标签: flutterflutter-providerflutter-navigation

解决方案


推荐阅读