Search code examples
flutterbloccubit

When Using "BlocBuilder" in "MultiBlocProvider" I have get error


I am new in flutter .I am tried googling but I cant fix my problem. I used "MultiBlocProvider" for manage stats . I want change dark mode state like bellow.

ThemeCubit.dart

part 'theme_state.dart';

class ThemeCubit extends HydratedCubit<ThemeState> {
   ThemeCubit() : super(ThemeState(AppThemes.lightTheme));

   void getTheme(ThemeState state) {
       emit(state);
   }

  @override
  ThemeState? fromJson(Map<String, dynamic> json) {
    return json['isDark'] as bool
        ? ThemeState(AppThemes.darkTheme)
        : ThemeState(AppThemes.lightTheme);
  }

 @override
 Map<String, bool>? toJson(ThemeState state) {
    return {'isDark': state.themeData.brightness == Brightness.dark};
 }
}

ThemeState.dart

part of 'theme_cubit.dart';

@immutable
class ThemeState extends Equatable {
  final ThemeData themeData;

  const ThemeState(this.themeData);

  @override
  List<Object?> get props => [themeData];
}

main.dart

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

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
        return  MultiBlocProvider(
           providers: [
              BlocProvider(
                  lazy: true,
                 create: (context) => ThemeCubit(),
              ),
           ],
          child:BlocBuilder<ThemeCubit, ThemeState>(
             builder: (context,state) {
                 return MaterialApp(           
                     debugShowCheckedModeBanner: false,            
                     title: 'Flutter Production Boilerplate',
                     theme: state.themeData, //ThemeMode.dark,
                     home: const MyHomePage(title: 'Flutter Demo Home Page'),
                 );
                },
               ),
              );
            }
         }

settingScreen.dart

Positioned(
                  top: 60 - widget.offset / 2,
                  left: 20,
                  child: Builder(builder: (context) {

                    return Switch(
                        value:newValue ,
                        onChanged: (value) {
                          BlocProvider.of<ThemeCubit>(context).getTheme(ThemeState(
                              newValue ? AppThemes.darkTheme : AppThemes.lightTheme));
                        });
                  })
            ),

This code works properly when used "BlocProvider" . But when I used "MultiBlocProvider", I get bellow error.

The following assertion was thrown attaching to the render tree: 'package:flutter/src/widgets/framework.dart': Failed assertion: line 4357 pos 14: 'owner!._debugCurrentBuildTarget == this': is not true.

Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause. In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.md

When the exception was thrown, this was the stack: #2 Element.rebuild. (package:flutter/src/widgets/framework.dart:4357:14) #3 Element.rebuild (package:flutter/src/widgets/framework.dart:4360:6) #4 ComponentElement._firstBuild (package:flutter/src/widgets/framework.dart:4643:5) #5 ComponentElement.mount (package:flutter/src/widgets/framework.dart:4638:5) #6 Element.inflateWidget (package:flutter/src/widgets/framework.dart:3673:14) #7 Element.updateChild (package:flutter/src/widgets/framework.dart:3425:18) #8 RenderObjectToWidgetElement._rebuild (package:flutter/src/widgets/binding.dart:1198:16) #9 RenderObjectToWidgetElement.mount (package:flutter/src/widgets/binding.dart:1167:5) #10 RenderObjectToWidgetAdapter.attachToRenderTree. (package:flutter/src/widgets/binding.dart:1112:18) #11 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2573:19) #12 RenderObjectToWidgetAdapter.attachToRenderTree (package:flutter/src/widgets/binding.dart:1111:13) #13 WidgetsBinding.attachRootWidget (package:flutter/src/widgets/binding.dart:944:7) #14 WidgetsBinding.scheduleAttachRootWidget. (package:flutter/src/widgets/binding.dart:924:7) (elided 13 frames from class _AssertionError, class _RawReceivePortImpl, class _Timer, dart:async, and dart:async-patch)

How can I fix it?


Solution

  • I added bellow code to ThemeCubit.dart :

     bool isDarkMode = false;
     ThemeMode currentTheme(){
     isDarkMode?_setTheme(ThemeMode.dark) : _setTheme(ThemeMode.light);
    
          return isDarkMode?ThemeMode.dark : ThemeMode.light;
     }
    
     void updateTheme(bool isDarkMode) {
     this.isDarkMode = isDarkMode;
    
    }
    

    and change main.dart :

      Widget build(BuildContext context) {
         return  MultiBlocProvider(
            providers: [
               BlocProvider(
                 create: (context) => ThemeCubit(),
              ),
           ],
           child:ElderlyApp(),     
        );
      }
      class ElderlyApp extends StatefulWidget {
         const ElderlyApp({Key? key,}) : super(key: key);
         @override
         _ElderlyAppState createState() => _ElderlyAppState();
      }
    
      class _ElderlyAppState extends State<ElderlyApp> with WidgetsBindingObserver {
    
         @override
           void initState() {
               WidgetsBinding.instance!.addObserver(this);
               super.initState();
           }
    
          @override
         void didChangePlatformBrightness() {
            context.read<ThemeCubit>().currentTheme();
           super.didChangePlatformBrightness();
         }
    
         @override
         void dispose() {
            WidgetsBinding.instance!.removeObserver(this);
            super.dispose();
        }
        @override
        Widget build(BuildContext context) {
            return MaterialApp(
            title: 'Flutter Production Boilerplate',
            theme: AppThemes.lightTheme,
            darkTheme: AppThemes.darkTheme,
            themeMode: context.select(
              (ThemeCubit cubit) => cubit.currentTheme()), //ThemeMode.dark,
            debugShowCheckedModeBanner: false,
            home: const MyHomePage(title: 'Flutter Demo Home Page'),
        );
       }
      }
    

    and change code in seetingScreen.dart

    Positioned(
       top: 60 - widget.offset / 2,
       left: 20,
       child: Builder(builder: (context) {
       bool isDark = context.select((ThemeCubit themeCubit) =>
                   themeCubit.state.themeMode) ==ThemeMode.dark ? true: false;
       return Switch(
                    value: context.read<ThemeCubit>().isDarkMode,
                    onChanged: (value) {
                    context.read<ThemeCubit>().updateTheme(value);
                  });
        })),