You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Cubit内部布尔值修改及状态控制Widget显示实现问题

存在的问题
  • 状态设计错误:你当前的Cubit继承自Cubit<bool>,仅支持单个布尔值作为全局状态,但你需要控制两个独立的布尔变量one、two,且这两个变量定义为Cubit的类属性,没有纳入状态管理范围,调用emit不会触发这两个属性的更新。
  • Dart值传递特性限制:你在changeValue方法中传入布尔参数,修改的只是方法内的局部变量副本,根本不会修改Cubit类中的one、two属性。
  • 每次主动创建新的Cubit实例:BlocBuilder和点击事件中都写了ChangeBoolCubit().one,这里每次都会新建一个独立的Cubit实例,拿到的永远是初始值,和你通过BlocProvider挂载在上下文的实例完全无关,也不会响应状态更新。
  • 没有使用BlocBuilder提供的state参数:BlocBuilder的builder回调已经返回了最新的状态值,你完全没有用到这个参数,反而自己新建实例拿属性,自然不会更新。
修复实现

首先定义包含两个布尔值的状态类,支持拷贝更新:

class BoolState {
  final bool one;
  final bool two;

  BoolState({required this.one, required this.two});

  // 拷贝方法,方便修改指定属性生成新状态
  BoolState copyWith({
    bool? one,
    bool? two,
  }) {
    return BoolState(
      one: one ?? this.one,
      two: two ?? this.two,
    );
  }
}

修改Cubit定义,继承自Cubit<BoolState>:

class ChangeBoolCubit extends Cubit<BoolState> {
  // 初始状态one为false,two为true
  ChangeBoolCubit() : super(BoolState(one: false, two: true));

  // 切换one的值
  void toggleOne() {
    emit(state.copyWith(one: !state.one));
  }

  // 切换two的值
  void toggleTwo() {
    emit(state.copyWith(two: !state.two));
  }
}

修改页面View代码,使用BlocBuilder返回的state参数,调用正确的实例方法:

class BoolView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Changing Bool')),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.center,
        children: [
          Center(
            child: BlocBuilder<ChangeBoolCubit, BoolState>(
              builder: (context, state) {
                // 直接用回调返回的state拿最新值
                return state.one
                    ? Text('TRUE: ${state.one}')
                    : Text('FALSE: ${state.one};');
              },
            ),
          ),
          Center(
            child: BlocBuilder<ChangeBoolCubit, BoolState>(
              builder: (context, state) {
                return state.two
                    ? Text('TRUE: ${state.two}')
                    : Text('FALSE: ${state.two};');
              },
            ),
          ),
        ],
      ),
      floatingActionButton: Column(
        mainAxisAlignment: MainAxisAlignment.end,
        crossAxisAlignment: CrossAxisAlignment.end,
        children: <Widget>[
          FloatingActionButton(
            child: const Icon(Icons.add),
            // 调用上下文挂载的Cubit实例的toggleOne方法
            onPressed: () => context.read<ChangeBoolCubit>().toggleOne(),
          ),
          const SizedBox(height: 8),
          FloatingActionButton(
            child: const Icon(Icons.remove),
            // 调用上下文挂载的Cubit实例的toggleTwo方法
            onPressed: () => context.read<ChangeBoolCubit>().toggleTwo(),
          ),
        ],
      ),
    );
  }
}

最后别忘了在BoolView的父组件中添加BlocProvider挂载Cubit实例:

BlocProvider(
  create: (context) => ChangeBoolCubit(),
  child: BoolView(),
)

内容的提问来源于stack exchange,提问作者mmcib

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 12:15:03