Set up 2222 AppLoading
To prove that app loading is indeed doing anything, some easy refactoring to use a loading screen are in order.
You appState has a property called isLoading. In a big app with
configuration, that'll probably always start as 'true', and then be switched
off when the configuration is complete. This bool is what Flutter will use to
render the loading screen.
For now, the HomePage will just render a loading spinner until the config
is loaded, and then it'll render with the full HomeScreen experience.
1. Add a LoadingView to HomeScreen
In your HomeScreenState widget...
// screens/home_screen.dart
class HomeScreen extends StatefulWidget {/*...*/}
class HomeScreenState extends State<HomeScreen> {
// new
AppState appState;
// new
Widget get _pageToDisplay {
if (appState.isLoading) {
return _loadingView;
} else {
return _homeView;
}
}
// new
Widget get _loadingView {
return new Center(
child: new CircularProgressIndicator(),
);
}
// new
Widget get _homeView {
return new Center(child: new Text(appState.user.displayName));
}
Widget build(BuildContext context) {
// This is the InheritedWidget in action.
// You can reference the StatefulWidget that
// wraps it like this, which allows you to access any
// public method or property on it.
var container = AppStateContainer.of(context);
// For example, get grab its property called state!
appState = container.state;
// Everything this build method is called, which is when the state
// changes, Flutter will 'get' the _pageToDisplay widget, which will
// return the screen we want based on the appState.isLoading
Widget body = _pageToDisplay;
return new Scaffold(
appBar: new AppBar(
title: new Text('Suite'),
),
// Replace the hardcoded widget
// with our widget that switches.
body: body,
);
}
}
This is neat. It doesn't look like much now, but you can call methods on that
variable called container, which can call setState and tell Flutter to
rerender any widget in the tree that relies on that piece of state.
2. Add Loading Logic to AppStateContainer
Now, you can add logic to your app state container, which will tell the home screen to rerender based on isLoading.
In _AppStateContainerState...
// app_state_container.dart
class AppStateContainer extends StatefulWidget {/*..*/}
class _AppStateContainerState extends State<AppStateContainer> {
// Pass the state through because on a StatefulWidget,
// properties are immutable. This way we can update it.
AppState state;
// Updated
void initState() {
super.initState();
if (widget.state != null) {
state = widget.state;
} else {
state = new AppState.loading();
// fake some config loading
startCountdown();
}
}
// If all goes well, when you launch the app
// you'll see a loading spinner for 2 seconds
// Then the HomeScreen main view will appear
Future<Null> startCountdown() async {
const timeOut = const Duration(seconds: 2);
new Timer(timeOut, () {
setState(() => state.isLoading = false);
});
}
// So the WidgetTree is actually
// AppStateContainer --> InheritedStateContainer --> The rest of your app.
Widget build(BuildContext context) {
return new _InheritedStateContainer(
data: this,
child: widget.child,
);
}
}
//...
Once this is done, your app should be doing this:

That's proof that your inherited widget is working, and setting state at the proper time. Nice!