Changing theme using GetX

Issue

I want to change the theme to redTheme only when I’m on a specific route. For that purpose, I’ve used routingCallback like

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      title: 'App',
      theme: defaultTheme(context),
      initialRoute: AppPages.INITIAL,
      getPages: AppPages.routes,
      routingCallback: (routing) => _routingCallback(context, routing),
    );
  }

  _routingCallback(BuildContext context, Routing routing) {
    if (routing.current == Routes.PURSUE_MODE) {
      _changeThemeIfNeeded(redTheme(context));
    } else {
      _changeThemeIfNeeded(defaultTheme(context));
    }
  }

  void _changeThemeIfNeeded(ThemeData theme) {
    Get.changeTheme(theme);
  }
}

Unfortunately, it’s causing

════════ Exception caught by widgets library
═══════════════════════════════════════════════════════ setState() or
markNeedsBuild() called during build. The relevant error-causing
widget was: Directionality
file:///Users/jakub/.pub-cache/hosted/pub.dartlang.org/get_navigation-3.12.0/lib/src/root/root_widget.dart:235:22
════════════════════════════════════════════════════════════════════════════════════════════════════

Because of that, I’ve wrapped theme changing in try-catch block, so I’m not getting exception at the start

  void _changeThemeIfNeeded(ThemeData theme) {
    try {
      if (Get.theme != theme) {
        Get.changeTheme(theme);
      }
    } catch (e) {
      print('Not ready e = $e');
    }
  }

But I believe there is more elegant approach to this problem using Get framework?

Solution

I’m not really familiar with GetX. However, in order to avoid setState() or markNeedsBuild() called during build. error, you can use addPostFrameCallback, in your case, like this:

routingCallback: (routing) => WidgetsBinding.instance
      .addPostFrameCallback((_) => _routingCallback(context, routing)) 

Answered By – Riwen

Answer Checked By – David Goodson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.