Я в основном ищу способ начать загрузку данных или перейти к экрану входа в систему.
FutureProvider получает свое значение от SharedPreferences. Главный экран по умолчанию - это просто логотип со спиннером.
Если идентификатор пользователя принимает значение NULL, приложение должно перейти к экрану входа в систему, в противном случае оно должно вызвать метод, который начнет загрузку данных, а затем по завершении перейдет кглавная страница.
Можно ли этого достичь с помощью FutureProvider?
Я добавляю его в компоновку страницы, чтобы виджет страницы подписывался на поставщика:
Widget build(BuildContext context) {
userInfo = Provider.of<UserInfo>(context);
print('Building with $userInfo');
return PageWithLoadingIndicator();
....
Я добавил его в didChangeDependencies, чтобы отреагировать на изменение:
@override
void didChangeDependencies() {
print('Deps changed: $userInfo');
super.didChangeDependencies();
// userInfo = Provider.of<UserInfo>(context); // Already building, can't do this.
// print('And now: $userInfo');
if (userInfo == null) return;
if (userInfo.userId != null) {
startUp(); // Run when user is logged in
} else {
tryLogin(); // Navigate to Login
}
}
И поскольку я не могу использовать Provider.of в initState, я добавил PostFrameCallback
void postFrame(BuildContext context) {
print('PostFrame...');
userInfo = Provider.of<UserInfo>(context);
}
Main очень просто -сейчас он просто настраивает MultiProvider с одним FutureProvider.
class MyApp extends StatelessWidget {
Future<UserInfo> getUserInfo() async {
String token = await UserPrefs.token;
return UserInfo.fromToken(
token,
);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App One',
theme: ThemeData(
primarySwatch: Colors.purple,
),
home: MultiProvider(
providers: [FutureProvider<UserInfo>(builder: (_) => getUserInfo())],
child: LoadingScreen(),
),
);
}
}
Проблема в том, что, как сейчас, я вижу из операторов печати, что didChangeDependencies вызывается дважды, но значение userInfoвсегда равен null, хотя build () в конечном итоге получает экземпляр UserInfo, что видно из оператора print в методе build ().
Я предполагаю, что могу добавить некоторую логику в метод сборки, но это кричит о моих чувствах как о неподходящем месте, чтобы сделать это ... возможно, это не так плохо, как я думаю?