marcglasberg / async_redux

Flutter Package: A Redux version tailored for Flutter, which is easy to learn, to use, to test, and has no boilerplate. Allows for both sync and async reducers.
Other
230 stars 41 forks source link

recommendation how to switch App brightness #133

Closed ValeriusGC closed 2 years ago

ValeriusGC commented 2 years ago

Hi there. Deep in my Settings i execute some action with flag isDarkMode. How can i switch brightness on the top of my app?

  @override
  Widget build(BuildContext context) {
    return OverlaySupport.global(
      child: StoreProvider<AppState>(
        store: Config.store,
        child: Builder(
            builder: (context) {
              return MaterialApp.router(
                title: 'FuSt',
                theme: ThemeData(
                  // here there are not reactivity ((
                  brightness: StoreProvider.state<AppState>(context)!.isDarkMode ? Brightness.dark : Brightness.light,
                  primaryColor: Colors.green.shade800,
                  visualDensity: VisualDensity.adaptivePlatformDensity,
                ),
ValeriusGC commented 2 years ago

I did it in this manner. What do you think about it?


class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return OverlaySupport.global(
      child: StoreProvider<AppState>(
        store: Config.store,
        child: const AppConnector(),
      ),
    );
  }
}

/// Application widget
class App extends StatelessWidget {
  const App({Key? key, required this.isDarkMode}) : super(key: key);

  final bool isDarkMode;

  @override
  Widget build(BuildContext context) {
    return Builder(
        builder: (context) {
          return MaterialApp.router(
            title: 'FuSt',
            theme: ThemeData(
              brightness: isDarkMode ? Brightness.dark : Brightness.light,
              primaryColor: Colors.green.shade800,
              visualDensity: VisualDensity.adaptivePlatformDensity,
            ),
            routerDelegate: AppRouter.delegate(),
            routeInformationProvider: AppRouter.routeInfoProvider(),
            routeInformationParser: AppRouter.defaultRouteParser(),
            builder: (ctx, router) {
              initContextApp(ctx);
              return router ?? const SizedBox();
            },
            localizationsDelegates: context.localizationDelegates,
            supportedLocales: context.supportedLocales,
            locale: context.locale,
          );
        }
    );
  }
}

/// App widget connector
class AppConnector extends StatelessWidget {
  const AppConnector({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    debugPrint('$now: AppConnector.build.1:');

    return StoreConnector<AppState, _Vm>(
      vm: () => _Factory(),
      builder: (context, vm) {
        debugPrint('$now: HomePageConnector.build.2: ${vm.isDarkMode}');
        return App(
          isDarkMode: vm.isDarkMode,
        );
      },
    );
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

class _Factory extends AppVmFactory {
  @override
  _Vm fromStore() {
    return _Vm(
      isDarkMode: state.isDarkMode,
    );
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////

class _Vm extends Vm {
  final bool isDarkMode;

  _Vm({
    required this.isDarkMode,
  }) : super(equals: [isDarkMode]);
}
marcglasberg commented 2 years ago

Yes, the second way is the correct way. The first one you are reading the state directly, but it doesn't know when the state changes, so it doesn't rebuild. I actually never read the state directly like this, and don't know a lot about how to make it work that way. The second way is the way I always do it.