Flutter 检索运行时更改的主题数据问题
简而言之,我的故事是,我可以成功地动态更改应用程序主题,但在使用最后选择的Flutter 检索运行时更改的主题数据问题,flutter,asynchronous,dart,Flutter,Asynchronous,Dart,简而言之,我的故事是,我可以成功地动态更改应用程序主题,但在使用最后选择的主题数据启动应用程序时,我失败了 这是主要的。省道: import "./helpers/constants/themeConstant.dart" as themeProfile; class MyApp extends StatelessWidget { Widget build(BuildContext context) { return MultiProvider( providers: [ /
主题数据启动应用程序时,我失败了
这是主要的。省道:
import "./helpers/constants/themeConstant.dart" as themeProfile;
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
//Several ChangeNotifierProviders
],
child: Consumer<AuthenticateProvider>(
builder: (ctx, authData, _) => ChangeNotifierProvider<ThemeChanger>(
create: (_) {
ThemeData themeToBeSet;
themeProfile.setInitialTheme().then((themeData) {
themeToBeSet = themeData;
});
return ThemeChanger(themeToBeSet);
},
child: _MaterialAppWithTheme(authData),
)
)
);}}
在这里,我使用shared\u preferences.dart
包来存储和检索主题数据信息。如果调试此块,我会看到我的selectedTheme
变量已成功设置为其中一个主题数据。但是,由于某种原因,我无法找到,main.dart
上的themetobset
变量未分配给我的setInitialTheme()
方法的结果
是因为异步吗?但是,Dart不是在用.then()
等待一个异步方法吗
为了不给我的其他部分留下任何问号,我还分享了Mechanger课程
class ThemeChanger with ChangeNotifier {
ThemeData _themeData;
ThemeChanger(
this._themeData
);
getTheme() => _themeData;
setTheme(ThemeData theme) {
_themeData = theme;
notifyListeners();
}
}
还有,主题材料
class _MaterialAppWithTheme extends StatelessWidget {
final AuthenticateProvider authData;
_MaterialAppWithTheme(
this.authData,
);
Widget build(BuildContext context) {
final theme = Provider.of<ThemeChanger>(context);
return MaterialApp(
title: 'Game Shop Demo',
theme: theme.getTheme(),
home: authData.isLogedin ?
HomeScreen(authData.userId) :
FutureBuilder(
future: authData.autoLogin(),
builder: (ctx, authResult) => authResult.connectionState == ConnectionState.waiting ?
SplashScreen():
LoginScreen()
),
routes: {
//Several named routes
},
);
}
}
class\u MaterialAppWithTheme扩展了无状态小部件{
最终身份验证提供者身份验证数据;
_主题材料(
这个.authData,
);
小部件构建(构建上下文){
最终主题=提供者(上下文);
返回材料PP(
标题:“游戏商店演示”,
theme:theme.getTheme(),
主页:authData.isLogedin?
主屏幕(authData.userId):
未来建设者(
future:authData.autoLogin(),
生成器:(ctx,authResult)=>authResult.connectionState==connectionState.waiting?
SplashScreen():
LoginScreen()
),
路线:{
//几个命名路线
},
);
}
}
正如我所怀疑的,我误用了.then()
当您使用.then()
时,我以为Dart正在等待,但在遇到这个问题后,我了解到它没有等待
因此,我将setInitialTheme()
方法带到ThemeChanger
类中(它以前在另一个类中),并在构造函数中调用它。这里是它的最终版本
class ThemeChanger with ChangeNotifier {
ThemeData _themeData;
ThemeChanger() {
_setInitialTheme();
}
getTheme() => _themeData;
setTheme(ThemeData theme) {
_themeData = theme;
notifyListeners();
}
Future<ThemeData> _setInitialTheme() async {
final preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey(ApplicationConstant.sharedTheme)) {
_themeData = appThemeDataDark;
final currentThemeInfo = json.encode({
"themeStyle": ApplicationConstant.darkAppTheme
});
preferences.setString(ApplicationConstant.sharedTheme, currentThemeInfo);
return _themeData;
}
else {
final extractedThemeInfo = json.decode(preferences.getString(ApplicationConstant.sharedTheme)) as Map<String, dynamic>;
final chosenTheme = extractedThemeInfo["themeStyle"];
if (chosenTheme == ApplicationConstant.lightAppTheme) {
_themeData = appThemeDataLight;
return _themeData;
}
else if (chosenTheme == ApplicationConstant.darkAppTheme) {
_themeData = appThemeDataDark;
return _themeData;
}
else {
_themeData = appThemeDataDark; //Its better to define a third theme style, something like appThemeDefault, but in order not to spend more time on dummy stuff, I skip that part
return _themeData;
}
}
}
}
现在,应用程序正在启动,最后选择的主题数据
的指针存储在SharedReferences
中
class ThemeChanger with ChangeNotifier {
ThemeData _themeData;
ThemeChanger() {
_setInitialTheme();
}
getTheme() => _themeData;
setTheme(ThemeData theme) {
_themeData = theme;
notifyListeners();
}
Future<ThemeData> _setInitialTheme() async {
final preferences = await SharedPreferences.getInstance();
if (!preferences.containsKey(ApplicationConstant.sharedTheme)) {
_themeData = appThemeDataDark;
final currentThemeInfo = json.encode({
"themeStyle": ApplicationConstant.darkAppTheme
});
preferences.setString(ApplicationConstant.sharedTheme, currentThemeInfo);
return _themeData;
}
else {
final extractedThemeInfo = json.decode(preferences.getString(ApplicationConstant.sharedTheme)) as Map<String, dynamic>;
final chosenTheme = extractedThemeInfo["themeStyle"];
if (chosenTheme == ApplicationConstant.lightAppTheme) {
_themeData = appThemeDataLight;
return _themeData;
}
else if (chosenTheme == ApplicationConstant.darkAppTheme) {
_themeData = appThemeDataDark;
return _themeData;
}
else {
_themeData = appThemeDataDark; //Its better to define a third theme style, something like appThemeDefault, but in order not to spend more time on dummy stuff, I skip that part
return _themeData;
}
}
}
}
class MyApp extends StatelessWidget {
Widget build(BuildContext context) {
return MultiProvider(
providers: [
//Several ChangeNotifierProviders
],
child: Consumer<AuthenticateProvider>(
builder: (ctx, authData, _) => ChangeNotifierProvider<ThemeChanger>(
create: (_) => ThemeChanger(),
child: _MaterialAppWithTheme(authData),
)
)
);
}
}