Maybe I am approaching it the wrong way… I intend to adapt the Home Screen to the user data that I find locally stored. So I create a BLoC, check the local DB, then (in coding aka widget order) I create a MaterialApp
with the Home Screen based on the data I found.
class App extends StatelessWidget {
const App({
super.key,
required this.appDataRepository});
final AppDataRepository appDataRepository;
@override
Widget build(BuildContext context) {
return MultiRepositoryProvider(
providers: [
RepositoryProvider.value(
value: appDataRepository)
],
child: BlocProvider(
create: (_) => AppBloc(GetUserUC(clientRepository, operatorRepository))..add(AppLaunched()),
child: const AppView(),
),
);
}
}
class AppView extends StatelessWidget {
const AppView({super.key});
@override
Widget build(BuildContext context) {
final AppState state = context.read<AppBloc>().state;
print('app state ${state.role.name} ${state.startPage}');
return MaterialApp(
theme: MobileTheme.light,
darkTheme: MobileTheme.dark,
home: state.startPage == StartPage.selectRole
? const UserDataPage()
: state.startPage == StartPage.clientHome
? const HomePageClient()
: state.startPage == StartPage.operatorHome
? const HomePageOperator()
: const HomePageClient(), //TODO
);
}
}
In my BLoC there is also a print command which shows that in timely order the MaterialApp is build before BLoC fetches the data and yields a new state.
How would I best wait for the state update to come before initializing the MaterialApp. Somehow I can hardly think of anything elegant with a FutureBuilder
. Or is there a completely different approach that makes more sense?
2
Answers
You should initialize the material app in the App Class.
After that in the AppView, you can go for a
Splash Screen
or aLoading Screen
Then you should wrap the body of the AppView with a
Bloc Listener
and then inside the Bloc Listener, according to the state change you can navigate where ever you want in your app.With bloc you can handle all state management in the bloc and provide states depending on the current state to your page (like you did in your code snippet).
And in the same way you can also build a kind of "loading", or "waiting" page when waiting for the bloc to do some work.
The "MaterialApp" widget and other widgets should then be put above your page.
I put together a small example that should show the initialization of a bloc with the page rebuilding.
You can run the following example directly as it is:
In the same way you can of course also load some data inside of the bloc, show some kind of loading page state during it and then navigate to another page as soon as the data is loaded (by providing a new state with the data, or using the navigator inside of the bloc with a shared build context). The new Page could then also accept a parameter for the data, etc…