0

有一个问题,我现在坐了几天。有一个应用程序:

  • 根据 AUTH 状态,显示“LoginScreen”或“MainScreen”。

  • 在 MainScreen 中,我使用屏幕(HomeScreen、ShoppingScreen、MyFavorites)设置底部导航

  • 我还使用 MultiProvider 在那里设置了我的 StreamProviders(那些依赖于 Auth)
  • 当我在 HomeScreen 上使用 Provider.of(context) 时,它的工作原理应该是这样
  • 但是当我使用时:

    `Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) => ProfileScreen(),
      ),
    );
    

` 并在此处使用 Provider.of(context) 我得到“找不到正确的提供者....在此之上...小部件

我阅读了一些关于这方面的问题,解决方案是在 MaterailApp 上方取消提供程序,在我的情况下我不能这样做,因为我只能在 Auth 成功后设置这些。

尝试将上下文(从 HomeScreen)传递给 ProfileScreen(通过构造函数)并且有效,但是当 UserData 的值更改时,它没有更新屏幕(猜测是因为不同的“上下文”)

我在这里做错了什么,有什么想法吗?:S

4

2 回答 2

2

提供者是“范围的”。

这意味着如果将它们放置在屏幕内,则无法在该屏幕外访问它们。

这意味着,如果提供程序是有范围的,但需要在创建它的路由之外访问,我们有两种解决方案:

  • 取消范围提供程序。这涉及将提供者移动到需要获取值的两个小部件的共同祖先。

    如果这两个小部件位于两个不同的路线上,那么它基本上意味着“将提供程序移到MaterialApp/上方CupertinoApp

  • 手动将提供程序传递到新屏幕(使用时需要Navigator.push

    这个想法是,我们有两个提供者,而不是一个提供者,它们都使用与此处解释的相同的值 请参阅如何使用提供者将 ChangeNotifier 范围限定为某些路由?举一个实际的例子。

    对于Navigator.push,这可能看起来像:

    final myModel = Provider.of<MyModel>(context);
    Navigator.push(
      context,
      MaterialPageRoute(
        builder: (_) =>
          ChangeNotifierProvider.value(
            value: myModel,
            child: MyScreen(),
        ),
      ),
    );
    
于 2019-10-08T11:43:53.870 回答
1

请确保您的应用程序的根小部件是ProviderWidget,它应该是MaterialWidget. 如果已经是这种情况,我将需要您的代码进行调查。像这样的东西

class AppState {
 User loggedInUser;

 bool get isLoggedIn {
  return loggedInUser != null;
 }

 // Other states as per the requirements
 // ...
}
于 2019-10-08T11:38:10.723 回答