在“MultiBlocProvider”中使用“BlocBuilder”时出现错误

Posted

技术标签:

【中文标题】在“MultiBlocProvider”中使用“BlocBuilder”时出现错误【英文标题】:When Using "BlocBuilder" in "MultiBlocProvider" I have get error 【发布时间】:2022-01-05 13:20:37 【问题描述】:

我是 Flutter 的新手。我尝试使用谷歌搜索,但无法解决我的问题。我使用“MultiBlocProvider”来管理统计信息。我想像下面这样改变暗模式状态。

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];

ma​​in.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));
                        );
                  )
            ),

此代码在使用 "BlocProvider" 时可以正常工作。但是当我使用“MultiBlocProvider”时,出现以下错误。

以下断言被抛出附加到渲染树: 'package:flutter/src/widgets/framework.dart':断言失败:行 4357 pos 14:'owner!._debugCurrentBuildTarget == this':不正确。

要么断言表明框架本身存在错误,要么我们 应在此错误消息中提供更多信息 帮助您确定并解决根本原因。在任一情况下, 请在 GitHub 上提交错误报告此断言:https://github.com/flutter/flutter/issues/new?template=2_bug.md

当异常被抛出时,这是堆栈: #2 元素重建。 (包: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。 (包: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) (省略13帧 来自 _AssertionError 类、_RawReceivePortImpl 类、_Timer 类、 dart:async 和 dart:async-patch)

我该如何解决?

【问题讨论】:

请在问题中发布您的完整错误日志。 @Amir_P 我编辑了我的问题 【参考方案1】:

我在 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;


并更改 ma​​in.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'),
    );
   
  

并更改 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);
              );
    )),

【讨论】:

以上是关于在“MultiBlocProvider”中使用“BlocBuilder”时出现错误的主要内容,如果未能解决你的问题,请参考以下文章

MultiBlocProvider 未实例化所有 bloc 提供程序 - 如何正确使用 MultiBlocProvider?

Flutter MultiBlocProvider 性能

Flutter BLOC 和 Provider 如何注册在一起

使用不包含 PhoneAuthenticationBloc 类型的 Bloc 的上下文调用 BlocProvider.of()。扑

为什么在定义宏中使用括号会产生错误?

使用指针在函数中交换数值