StateNotifierProvider 在应用程序重新启动之间不保持状态

问题描述

使用 flutter_riverpod: ^0.12.4 并在 android 模拟器和物理设备上进行测试。

在重新启动应用程序后,登录屏幕 state 值没有保留在 StateNotifierProvider 中是我做错了什么?

accountSetupProvider 的 state 认为介绍屏幕。单击介绍屏幕的 onpressed 按钮后,state 将更新为登录屏幕,并正确触发重建以显示登录屏幕。

但是,在抖动热重启或打开/关闭应用程序后,将显示介绍屏幕,而不是登录屏幕。 state 是否应该在点击介绍屏幕中的 onpressed 后设置为登录屏幕,并在重新启动之间持续存在并导致跳过介绍屏幕并显示登录屏幕?

如下所示,main.dart一个初始 AppRoutes.root 路由。在 app_router.dart 中,这个“根”屏幕打开 root_screen.dart,它是一个 ConsumerWidget,它是 watch(ing) 我在 account_setup_provider.dart 中名为“accountSetupProvider”的 StateNotifierProvider。

ma​​in.dart

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();

  runApp(
    ProviderScope(
      child: MyApp(),),);
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      initialRoute: AppRoutes.root,onGenerateRoute: (settings) => AppRouter.onGenerateRoute(settings),);
  }
}

app_router.dart

class AppRoutes {
  static const String root = RootScreen.id;
  static const String intro = IntroScreen.id;
  static const String signIn = SignInScreen.id;
}

class AppRouter {
  static Route<dynamic> onGenerateRoute(RouteSettings settings) {
    final _args = settings.arguments;

    switch (settings.name) {
      case AppRoutes.root:
        return MaterialPageRoute<dynamic>(
          builder: (_) => RootScreen(),settings: settings,);
      case AppRoutes.intro:
        return MaterialPageRoute<dynamic>(
          builder: (_) => IntroScreen(),);
      case AppRoutes.signIn:
        return MaterialPageRoute<dynamic>(
          builder: (_) => SignInScreen(),);
    }
  }
}

root_screen.dart

class RootScreen extends ConsumerWidget {
  const RootScreen({Key key}) : super(key: key);
  static const String id = 'root_screen';

  @override
  Widget build(BuildContext context,ScopedReader watch) {
    final screen = watch(accountSetupProvider.state);

    if (screen == AppRoutes.signIn) {
      return SignInScreen();
    } else if (screen == AppRoutes.intro) {
      return IntroScreen();
    }
  }
}

intro_screen.dart(仅包括介绍屏幕的 onpressed 部分,我希望将状态设置为新屏幕,即使在抖动热重启或应用重启之后也是如此.)

onpressed: () {
  context
    .read(accountSetupProvider) // see accountSetupProvider StateNotifierProvider below.
    .setScreen(AppRoutes.signIn);
},

account_setup_provider.dart(初始化到 AppRoutes.intro 屏幕。)

class AccountSetupNotifier extends StateNotifier<String> {
  AccountSetupNotifier() : super(AppRoutes.intro);

  void setScreen(String screen) {
    state = screen;
  }
}

final accountSetupProvider = StateNotifierProvider<AccountSetupNotifier>((ref) {
  return AccountSetupNotifier();
});

解决方法

甚至不看你的代码,只看你的主题行,这对我来说一点也不奇怪。 “热重启”重置所有变量。怎么可能保存任何状态?您是否正在寻找“热重载”?