Stacked-Org/stacked

[bug]: Stacked_Themes ThemeManager

Closed this issue · 2 comments

Describe the bug

When I try to use ThemeService I get this error:

"LateInitializationError: Field '_themeManager' has not been initialized."

What operating system do you use?

Linux

Information about the installed tooling

No response

Steps to reproduce the issue

Create a new project with stacked.

Then import the stacked_themes.

Added the line to app.dart:
LazySingleton(classType: ThemeService),

Tried a lot of different setups, including changing the "app.locator" to reflect what is in the readme.

Added the ThemeService to the viewModel, but it also happens as a service.

final _themeService = locator<ThemeService>();

I changed the default methods in home_viewModel to this:

void showDialog() {
    _themeService.toggleDarkLightTheme();
  }

  void showBottomSheet(BuildContext context) {
    getThemeManager(context).toggleDarkLightTheme();
    rebuildUi();
  }

The showDialog function gives me the error:

LateInitializationError: Field '_themeManager' has not been initialized.

The other works, but doesn't rebuild the UI to the new Theme. (Another topic)

Expected behavior

No response

Screenshots

No response

Additional Context

No response

Forgot to mention my main class:

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  setPathUrlStrategy();
  await setupLocator(stackedRouter: stackedRouter);
  await ThemeManager.initialise();
  setupDialogUi();
  setupBottomSheetUi();
  runApp(const MainApp());
}

class MainApp extends StatelessWidget {
  const MainApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ThemeBuilder(
      defaultThemeMode: ThemeMode.light,
      darkTheme: ThemeData(
        brightness: Brightness.dark,
        scaffoldBackgroundColor: Colors.blue[900],
      ),
      lightTheme: ThemeData(
        brightness: Brightness.light,
        scaffoldBackgroundColor: Colors.blue[100],
      ),
      builder: (context, regularTheme, darkTheme, themeMode) => ResponsiveApp(
        builder: (_) => MaterialApp.router(
          theme: regularTheme,
          darkTheme: darkTheme,
          themeMode: ThemeMode.light,
          routerDelegate: stackedRouter.delegate(),
          routeInformationParser: stackedRouter.defaultRouteParser(),
        ),
      ).animate().fadeIn(
            delay: const Duration(milliseconds: 50),
            duration: const Duration(milliseconds: 400),
          ),
    );
  }
}

I got it to work.

For anyone who is having this issue, these are the steps:

Add the import in the pubspec.

In the app.dart add this line:

Singleton(classType: ThemeService, resolveUsing: ThemeService.getInstance),

Run "stacked generate"
Which adds this line in "app.locator":

locator.registerSingleton(ThemeService.getInstance());

I tried to add this manually without using Stacked generate and doesn't work.

In the main.dart add the Theme Builder really before the "MaterialApp.router":

Widget build(BuildContext context) {
    return ResponsiveApp(
      builder: (_) => ThemeBuilder(
        defaultThemeMode: ThemeMode.system,
        darkTheme: ThemeData(
          brightness: Brightness.dark,
          scaffoldBackgroundColor: Colors.blue[900],
        ),
        lightTheme: ThemeData(
          brightness: Brightness.light,
          scaffoldBackgroundColor: Colors.blue[100],
        ),
        builder: (context, regularTheme, darkTheme, themeMode) =>
            MaterialApp.router(
          theme: regularTheme,
          darkTheme: darkTheme,
          themeMode: themeMode,
          routerDelegate: stackedRouter.delegate(),
          routeInformationParser: stackedRouter.defaultRouteParser(),
        ),
      ).animate().fadeIn(
            delay: const Duration(milliseconds: 50),
            duration: const Duration(milliseconds: 400),
          ),
    );
  }

Got it working in this Test project. Probably will do a PR to create better documentation in the stacked_themes repo.