Update a widget from another one with Cubit Bloc
Solution 1
You should use a MultiBlocProvider.
The solution is :
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit() ),
BlocProvider(create: (context) => LoadingCubit() ),
],
child: Row(
children:[ AutoLoginButton(), LoadingWidget()]
)
)
Explanation: Flutter forms a tree like structure (Similar to DOM in HTML) for its visual element. Cubit/Blocs are attached to the elements, in this node tree. And are available to all child of a given node.
To Make it visible Cubit muts be moved upper in heiarchy:
Solution 2
You need to toggle loading on your AutoLoginButton onTap function with BlocProvider.of<LoadingCubit>(context).toggleLoading();
to trigger rebuild of loading widget, but to be able to call toggleLoading()
on LoadingCubit
you need to provide it above your AutoLoginButton
. So my solution for this would be:
MultiBlocProvider(
providers: [
BlocProvider(create: (context) => AutoLoginCubit()),
BlocProvider(create: (BuildContext context) => LoadingCubit()),
],
child: Row(
children: [
const AutoLoginButton(),
const LoadingWidget(),
],
),
),
Ardeshir ojan
Updated on November 26, 2022Comments
-
Ardeshir ojan over 1 year
I have two widgets on a screen a Loading Widget and a button widget I want to change the state of the loading widget every time I tap on the button.
loading widget
class LoadingWidget extends StatelessWidget { const LoadingWidget({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return BlocBuilder<LoadingCubit, bool>( bloc: BlocProvider.of<LoadingCubit>(context), builder: (context, loadingState) { return Center( child: Visibility( visible: BlocProvider.of<LoadingCubit>(context).state, child: const CircularProgressIndicator( backgroundColor: Color(0xFF2C2C2C), )), ); }); } }
loading cubit
class LoadingCubit extends Cubit<bool> { LoadingCubit() : super(true); toggleLoading() { emit(!state); } }
loading button
class AutoLoginButton extends StatelessWidget { const AutoLoginButton({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return BlocBuilder<AutoLoginCubit, bool>( bloc: BlocProvider.of<AutoLoginCubit>(context), builder: (context, autoLoginState) => InkWell( child: Row( children: [ Icon( autoLoginState == false ? Icons.check_box_outline_blank : Icons.check_box, ), ], ), onTap: () { BlocProvider.of<AutoLoginCubit>(context).toggleAutoLogin(); }, ), ); } }
button cubit
class AutoLoginCubit extends Cubit<bool> { AutoLoginCubit() : super(false){ initState().then((value) => emit(value)); } void toggleAutoLogin() async { if (state == false) { emit(true); } else { emit(false); } AutoLoginService().setAutoLoginState(state: state); } Future<bool> initState() async{ return await AutoLoginService().getAutoLoginState(); } }
the page
Row( children:[ BlocProvider( create: (context) => AutoLoginCubit(), child: const AutoLoginButton(), ), BlocProvider( create: (BuildContext context) => LoadingCubit(), child: const LoadingWidget()), ] )