Home > Net >  Update a widget from another one with Cubit Bloc
Update a widget from another one with Cubit Bloc

Time:02-28

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()),
     ]
       )

CodePudding user response:

You should use a enter image description here

To Make it visible Cubit muts be moved upper in heiarchy:

enter image description here

CodePudding user response:

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(),
            ],
          ),
        ),
  • Related