2

我在屏幕上有两个小部件,一个加载小部件和一个按钮小部件,我想在每次点击按钮时更改加载小部件的状态。

加载小部件

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),
                )),
          );
        });
  }
}

装载肘

class LoadingCubit extends Cubit<bool> {
  LoadingCubit() : super(true);

  toggleLoading() {
    emit(!state);
  }
}

加载按钮

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();
        },
      ),
    );
  }
}

钮肘

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();
  }
}

这页纸

Row(
 children:[
   BlocProvider(
       create: (context) => AutoLoginCubit(),
       child: const AutoLoginButton(),
       ),
   BlocProvider(
              create: (BuildContext context) => LoadingCubit(),
              child: const LoadingWidget()),
     ]
       )
4

2 回答 2

2

您应该使用MultiBlocProvider

解决方案是:

MultiBlocProvider(
 providers: [
    BlocProvider(create: (context) => AutoLoginCubit() ),
    BlocProvider(create: (context) => LoadingCubit() ),
 ],
 child: Row(
    children:[ AutoLoginButton(), LoadingWidget()]
 )
)

解释:Flutter 为它的视觉元素形成了一个树状结构(类似于 HTML 中的 DOM)。在此节点树中,Cubit/Blocs 附加到元素。并且可用于给定节点的所有子节点。

enter image description here

要使其可见,Cubit muts 必须在 heiarchy 中上移:

enter image description here

于 2022-02-28T08:10:31.937 回答
1

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(),
            ],
          ),
        ),
于 2022-02-28T08:20:07.270 回答