-
Notifications
You must be signed in to change notification settings - Fork 22
State management
Francesco Mineo edited this page Mar 15, 2019
·
2 revisions
By extending the AppStateModel interface it is possible to create a class to drive the AppStateProvider in order to provide the data to the widgets.
From the "theme changer" example:
class AppState extends AppStateModel {
List<MyTheme> themes;
StreamedValue<MyTheme> currentTheme;
AppState() {
print('-------APP STATE INIT--------');
themes = List<MyTheme>();
themes.addAll([
MyTheme(
name: 'Default',
brightness: Brightness.light,
backgroundColor: Colors.blue[50],
scaffoldBackgroundColor: Colors.blue[50],
primaryColor: Colors.blue,
primaryColorBrightness: Brightness.dark,
accentColor: Colors.blue[300],
),
MyTheme(
name: 'Teal',
brightness: Brightness.light,
backgroundColor: Colors.teal[50],
scaffoldBackgroundColor: Colors.teal[50],
primaryColor: Colors.teal[600],
primaryColorBrightness: Brightness.dark,
accentColor: Colors.teal[300],
),
MyTheme(
name: 'Orange',
brightness: Brightness.light,
backgroundColor: Colors.orange[50],
scaffoldBackgroundColor: Colors.orange[50],
primaryColor: Colors.orange[600],
primaryColorBrightness: Brightness.dark,
accentColor: Colors.orange[300],
),
]);
currentTheme = StreamedValue();
}
void setTheme(MyTheme theme) {
currentTheme.value = theme;
Prefs.savePref<String>('theme', theme.name);
}
@override
void init() async {
String lastTheme = await Prefs.getPref('theme');
if (lastTheme != null) {
currentTheme.value =
themes.firstWhere((theme) => theme.name == lastTheme);
} else {
currentTheme.value = themes[1];
}
}
@override
dispose() {
print('---------APP STATE DISPOSE-----------');
currentTheme.dispose();
}
}
void main() => runApp(App());
class App extends StatefulWidget {
@override
_AppState createState() => _AppState();
}
class _AppState extends State<App> {
AppState appState;
@override
void initState() {
super.initState();
appState = AppState();
}
@override
Widget build(BuildContext context) {
return AppStateProvider<AppState>(
appState: appState,
child: MaterialPage(),
);
}
}
class MaterialPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var theme = AppStateProvider.of<AppState>(context).currentTheme;
return ValueBuilder<MyTheme>(
stream: theme,
builder: (context, snapshot) {
return MaterialApp(
title: "Theme and drawer starter app",
theme: _buildThemeData(snapshot.data),
home: HomePage());
});
}
_buildThemeData(MyTheme appTheme) {
return ThemeData(
brightness: appTheme.brightness,
backgroundColor: appTheme.backgroundColor,
scaffoldBackgroundColor: appTheme.scaffoldBackgroundColor,
primaryColor: appTheme.primaryColor,
primaryColorBrightness: appTheme.primaryColorBrightness,
accentColor: appTheme.accentColor,
);
}
}
class SettingsPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
var appState = AppStateProvider.of<AppState>(context);
_buildThemesList() {
return appState.themes.map((MyTheme appTheme) {
return DropdownMenuItem<MyTheme>(
value: appTheme,
child: Text(appTheme.name, style: TextStyle(fontSize: 14.0)),
);
}).toList();
}
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: Text(
"Settings",
),
),
body: Container(
padding: EdgeInsets.all(8.0),
child: Column(
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
'Choose a theme:',
style: TextStyle(fontWeight: FontWeight.w500),
),
),
ValueBuilder<MyTheme>(
stream: appState.currentTheme,
builder: (context, snapshot) {
return DropdownButton<MyTheme>(
hint: Text("Status"),
value: snapshot.data,
items: _buildThemesList(),
onChanged: appState.setTheme,
);
}),
],
),
],
),
),
);
}
}