Flutter BlocBuilder 在 TextFormField 值中显示以前的状态

Flutter BlocBuilder displays previous state in TextFormField value

我正在尝试创建一个带有递增和递减按钮的 TextFormField,并且 TextFormField 也可以“手动”编辑。但是如果我使用 BLoC 有一个小问题 - state “落后”一个,这意味着当我第一次点击“+”时没有任何变化,但是当我第二次点击它时将其值更改为 21(依此类推......)。 我只用常规 Text 尝试了相同的实现,它按预期工作并正确更新。

我只是想知道我设置 TextFormField 的逻辑是否有缺陷:

小工具 class:

class MyCalculation extends StatefulWidget {
  const MyCalculation({Key? key}) : super(key: key);

  @override
  State<MyCalculation> createState() => _MyCalculationState();
}

class _MyCalculationState extends State<MyCalculation> {
  late TextEditingController _controller;
  late MyCalcBloc _bloc;

  @override
  void initState() {
    super.initState();
    _bloc = context.read();
    _controller.text = _bloc.state.amount.toString();
  }

  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<MyCalcBloc, MyCalcState>(builder: (context, state) {
      return MyCustomTextFormField(
          controller: _controller,
          onChanged: (value) {},
          onPlusTap: () {
            _bloc.add(PlusEvent());
            _bloc.text = '${state.amount}';
          },
          onMinusTap: () {});
    });
  }
}

BLoC class:

class MyCalcBloc extends Bloc<MyCalcEvent, MyCalcState> {
  MyCalcBloc() : super(const MyCalcState(amount: 20)) {
    on<IncrementFromEvent>(_onPlusEvent);
  }

  void _onPlusEvent(PlusEvent event, Emitter<MyCalcState> emit) {
    final newValue = state.amount + 1;
    emit(MyCalcState(amount: newValue));
  }
}

您应该在 BlocProvider 中实例化 TextEditingController,这样您将获得 TextFormField 中显示的“当前”state 值。

@override
  Widget build(BuildContext context) {
    return BlocBuilder<MyCalcBloc, MyCalcState>(builder: (context, state) {
      _controller = TextEditingController(text: state.amount.toString());
      return MyCustomTextFormField(
          controller: _controller,
          onChanged: (value) {},
          onPlusTap: () {
            _bloc.add(PlusEvent());
            _bloc.text = '${state.amount}';
          },
          onMinusTap: () {});
    });
  }