StateNotifierProvider не сохраняет состояние между перезапусками приложения
Использование flutter_riverpod: ^0.12.4 и тестирование в эмуляторе Android, а также на физическом устройстве.
Что я делаю не так, что значение экрана входа не сохраняется в StateNotifierProvider после перезапуска приложения?
По умолчанию для accountSetupProvider используется вводный экран. После нажатия кнопки onPressed на начальном экране отображается экран входа в систему, и он правильно запускает перестройку для отображения экрана входа в систему.
However, after a flutter hot restart or opening/closing the app, the Intro Screen, rather than the Sign In screen displays. Shouldn't the
state
, which now is set to the Sign In screen after clicking onPressed in the Intro Screen persist between restarts and cause the Intro Screen to be skipped and the Sign In screen to display?
As you can see below
main.dart
has an initial AppRoutes.root route. In
app_router.dart
, this "root" screen opens
root_screen.dart
, which is a
ConsumerWidget
that is
watch
(ing) my StateNotifierProvider called "accountSetupProvider" in
account_setup_provider.dart
.
main.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(),
settings: settings,
);
case AppRoutes.signIn:
return MaterialPageRoute<dynamic>(
builder: (_) => SignInScreen(),
settings: settings,
);
}
}
}
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 (only including the
onPressed
portion of intro screen, which I'm expecting to set the state to the new screen, even after a flutter hot restart or app restart.)
onPressed: () {
context
.read(accountSetupProvider) // see accountSetupProvider StateNotifierProvider below.
.setScreen(AppRoutes.signIn);
},
account_setup_provider.dart (inits to the
AppRoutes.intro
screen.)
class AccountSetupNotifier extends StateNotifier<String> {
AccountSetupNotifier() : super(AppRoutes.intro);
void setScreen(String screen) {
state = screen;
}
}
final accountSetupProvider = StateNotifierProvider<AccountSetupNotifier>((ref) {
return AccountSetupNotifier();
});
1 ответ
Даже не глядя на ваш код и глядя только на вашу тему, меня это совсем не удивляет. «Горячий перезапуск» сбрасывает все переменные. Как могло быть хоть какое-то государство? Вы вместо этого ищете "Hot Reload"?