在 "MultiBlocProvider" 中使用 "BlocBuilder" 时出现错误
When Using "BlocBuilder" in "MultiBlocProvider" I have get error
我是 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];
}
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));
});
})
),
此代码在使用“BlocProvider”时可以正常工作。但是当我使用“MultiBlocProvider”时,出现以下错误。
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)
我该如何解决?
我在 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;
}
并更改 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'),
);
}
}
并更改 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);
});
})),
我是 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];
}
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));
});
})
),
此代码在使用“BlocProvider”时可以正常工作。但是当我使用“MultiBlocProvider”时,出现以下错误。
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.mdWhen 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)
我该如何解决?
我在 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;
}
并更改 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'),
);
}
}
并更改 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);
});
})),