我正在尝试实现一个功能,其工作是使用 BLoC 和 SharedPreferences 在浅色和深色模式之间切换。通过调试打印我知道 DarkModeCubit 工作正常。然而,MainApp 不会立即接收新状态,而是仅在热重启后才接收。我不知道为什么。
这是我的主应用程序
void main() async {
WidgetsFlutterBinding.ensureInitialized(); // essential
await Firebase
.initializeApp(); // needed for Firebase, included Authentication and Firestore
//
// Initialization of all blocs used by most pages
//
runApp(
MultiBlocProvider(
providers: [
BlocProvider(create: ((context) => AuthenticationBloc())),
BlocProvider(create: ((context) => RefreshUserBloc())),
BlocProvider(create: ((context) => GetCurrentUserDocCubit())),
BlocProvider(create: ((context) => DarkModeCubit(PrefsState())))
],
child: MainApp(),
),
);
}
//
// Class of the Material App, the top of the widget tree
//
class MainApp extends StatefulWidget {
const MainApp({super.key});
@override
State<MainApp> createState() => _MainAppState();
}
class _MainAppState extends State<MainApp> {
final AppRouter _appRouter = AppRouter();
@override
void initState() {
super.initState();
//
// When the app starts we check if the user is already logged in. If so, we go to the home page, otherwise we go to the login page
//
WidgetsBinding.instance.addPostFrameCallback((_) {
BlocProvider.of<AuthenticationBloc>(context).add(AuthenticationStarted());
});
}
@override
Widget build(BuildContext context) {
//
// Build method of the Material App
//
return BlocBuilder<DarkModeCubit, ThemeMode>(
builder: (context, themeMode) {
debugPrint('MainApp: $themeMode');
return MaterialApp(
debugShowCheckedModeBanner: false,
//
// Theme of the app, with the colorScheme and the textTheme
//
theme: AppTheme.lightTheme,
darkTheme: AppTheme.darkTheme,
themeMode: themeMode,
//
// onGenerateRoute is the chosen routing system. It is defined in the app_router.dart file.
// When a route is called via Navigator.of(context).pushNamed('/routeName'), the onGenerateRoute method is called,
// and it returns the page associated with the routeName.
//
onGenerateRoute: _appRouter.onGenerateRoute,
//
// The initial route is the first route that is shown when the app starts.
// It is set to a BlocBuilder that listens to the AuthenticationBloc, and it redirects to the login page if the user is not logged in,
// otherwise it redirects to the home page.
//
initialRoute: '/',
);
},
);
}
}
这是肘节
class DarkModeCubit extends Cubit<ThemeMode> {
final PrefsState prefs;
DarkModeCubit(this.prefs) : super(ThemeMode.light) {
_loadTheme();
}
///
/// Method that loads the current {isDarkTheme}
///
void _loadTheme() async {
final isDarkTheme = await prefs.getThemePreference();
emit(isDarkTheme ? ThemeMode.dark : ThemeMode.light);
}
///
/// Method that changes the {isDarkTheme}
///
void toggleTheme({required bool isDarkTheme}) async {
await prefs.setThemePreference(isDarkTheme);
emit(isDarkTheme ? ThemeMode.dark : ThemeMode.light);
debugPrint('DarkModeCubit: $state');
}
}
这是我的首选项状态
class PrefsState {
/// Key that stores the location of the dark theme.
static const _isDarkThemeKey = 'isDarkTheme';
/// Method that retrieves the bool that indicates whether the theme is dark or light.
Future<bool> getThemePreference() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getBool(_isDarkThemeKey) ?? false;
}
/// Method that set the {isDarkTheme} property in the local storage.
Future<void> setThemePreference(bool isDarkTheme) async {
final prefs = await SharedPreferences.getInstance();
await prefs.setBool(_isDarkThemeKey, isDarkTheme);
}
}
阅读代码后,您的问题似乎在于如何在小部件树中创建块提供程序:
BlocProvider(create: ((context) => DarkModeCubit(PrefsState())))
/// or for readibility:
BlocProvider(
create: (
(context) => DarkModeCubit(PrefsState())
)
)
包裹您的
create
的括号看起来像是函数中存在一个函数,请将其从所有提供程序中删除,以便它们正确初始化。
BlocProvider(create: (_) => DarkModeCubit(PrefsState()))