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

从零构建的Bloc事件无法接收数据,请求技术排查

问题描述

首次从零构建Bloc组件,原本设定数值达到特定值时触发错误状态,但测试发现Bloc事件完全接收不到数据。已确认输入框内容变化时会触发DaysChangedEvent事件,但尝试对数据执行int.parse时返回null。

相关代码

Widget代码

class Daytextfield extends StatelessWidget {
  Daytextfield({
    Key? key,
    required this.digits,
    required this.hint,
  }) : super(key: key);

  final int digits;
  final String hint;
  final String texto = '';
  

  @override
  Widget build(BuildContext context) {
    
    final TextEditingController dias = TextEditingController(text: texto);
    Color color = Colors.black;
    

    return BlocConsumer<DaysBloc, DaysState>(
      listener: (context, state) {
        if(state is DaysIncorrectState){
          color = Colors.red;
        } else if (state is DaysCorrectState){
          color = Colors.green;
        }
      },
      builder: (context, state) {
        return TextFormField(
          onChanged: (value) {
            
            BlocProvider.of<DaysBloc>(context).add(DaysChangedEvent(texto: texto));
           print(state);
          //  var ree = int.tryParse(texto);
           print(texto);
          },
          controller: dias,
          keyboardType: TextInputType.number,
          textInputAction: TextInputAction.next,
          textAlign: TextAlign.center,
          cursorColor: Color.fromARGB(148, 66, 63, 63),
          style: Theme.of(context)
              .textTheme
              .headline1!
              .copyWith(fontSize: 20, color: color),

Bloc类代码

class DaysBloc extends Bloc<DaysEvent, DaysState> {
  int max = 360;

  DaysBloc() : super(DaysInitial()) {
    on<DaysChangedEvent>((event, emit) {
      if(event.texto == '123') {emit(DaysIncorrectState(texto: event.texto));}
      else emit(DaysCorrectState(texto: event.texto));


    });
  }
}

Event类代码

abstract class DaysEvent extends Equatable {
  const DaysEvent();

  @override
  List<Object> get props => [];
}

class DaysChangedEvent extends DaysEvent {
String texto;

  DaysChangedEvent({
    required this.texto,
  });
  
@override
  List<Object> get props => [texto];

}

State类代码

class DaysInitial extends DaysState {}

class DaysCorrectState extends DaysState {

 String texto;
 

  DaysCorrectState({
    required this.texto,
    
  });

@override
  List<Object> get props => [texto];
}

class DaysIncorrectState extends DaysState {

 String texto;
 

  DaysIncorrectState({
    required this.texto,
   
  });

@override
  List<Object> get props => [texto];
}
问题根源与修复

核心问题

  1. 传递错误的数据:onChanged回调里传的是类的初始空字符串texto,而非输入框当前的value,导致Bloc始终收到空值,int.tryParse自然返回null。
  2. 控制器位置错误:TextEditingController定义在build方法内,每次Widget重建都会重新初始化,无法保留输入内容。
  3. 颜色更新无效:color变量在build内定义,listener中修改后不会触发UI重建,State更新时color会被重置为黑色。

修复后的Widget代码

class Daytextfield extends StatelessWidget {
  Daytextfield({
    Key? key,
    required this.digits,
    required this.hint,
  }) : super(key: key);

  final int digits;
  final String hint;
  // 控制器放在类成员位置,避免每次build重建
  final TextEditingController dias = TextEditingController(text: '');

  @override
  Widget build(BuildContext context) {
    return BlocConsumer<DaysBloc, DaysState>(
      builder: (context, state) {
        // 直接在builder里根据状态取颜色,确保UI跟随状态更新
        Color color = Colors.black;
        if (state is DaysIncorrectState) {
          color = Colors.red;
        } else if (state is DaysCorrectState) {
          color = Colors.green;
        }

        return TextFormField(
          onChanged: (value) {
            // 传递输入框当前值value给事件
            BlocProvider.of<DaysBloc>(context).add(DaysChangedEvent(texto: value));
            print(state);
            print(value);
          },
          controller: dias,
          keyboardType: TextInputType.number,
          textInputAction: TextInputAction.next,
          textAlign: TextAlign.center,
          cursorColor: const Color.fromARGB(148, 66, 63, 63),
          style: Theme.of(context)
              .textTheme
              .headline1!
              .copyWith(fontSize: 20, color: color),
        );
      },
    );
  }
}

额外优化建议

在Bloc里处理字符串转整数的逻辑,更符合职责划分:

on<DaysChangedEvent>((event, emit) {
  final int? days = int.tryParse(event.texto);
  // 用数值判断替代字符串判断,逻辑更严谨
  if (days == 123) {
    emit(DaysIncorrectState(texto: event.texto));
  } else {
    emit(DaysCorrectState(texto: event.texto));
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 11:45:29