使用Bloc Flutter在微件重建之间保存输入值

cidc1ykv  于 2022-11-30  发布在  Flutter
关注(0)|答案(1)|浏览(95)

我有一个用Bloc包构建的表单。有两个带有文本字段的选项。在选项之间切换,我也用块和可见性小部件。当我选择一个选项小部件重建,名称和价格值删除。
在选择选项之间保存这些值的最佳方式是什么?
这是我的Bloc代码

class FormBloc extends Bloc<FormEvent, MyFormState> {
  FormBloc() : super(MyFormState()) {
    on<RadioButtonFormEvent>(_setRadioButtonState);
  }

  void _setRadioButtonState(
      RadioButtonFormEvent event, Emitter<MyFormState> emit) async {
    emit(RadioButtonFormState(
      buttonIndex: event.buttonIndex,
      buttonName: event.buttonName,
    ));
  }  
}

class MyFormState {}

class RadioButtonFormState extends MyFormState {
  final int buttonIndex;
  final String buttonName;

  RadioButtonFormState({
    required this.buttonIndex,
    required this.buttonName,

  });
}

abstract class FormEvent extends Equatable {}

class RadioButtonFormEvent extends FormEvent {
  final int buttonIndex;
  final String buttonName;

  RadioButtonFormEvent({
    required this.buttonIndex,
    required this.buttonName,

  });
  @override
  List<Object?> get props => [buttonIndex, buttonName,];
}

下面是表单代码

class FormInput extends StatelessWidget {
  const FormInput({super.key});

  @override
  Widget build(BuildContext context) {
    final formBlocWatcher = context.watch<FormBloc>().state;

    final nameController = TextEditingController();
    final priceController = TextEditingController();
    final formOneController = TextEditingController();
    final formTwoController = TextEditingController();
    final formThreeController = TextEditingController();
    String formOptionController = '';

    bool optionOneIsActive = true;
    bool optionTwoIsActive = false;

    if (formBlocWatcher is RadioButtonFormState) {
      switch (formBlocWatcher.buttonIndex) {
        case 0:
          formOptionController = formBlocWatcher.buttonName;
          break;
        case 1:
          optionTwoIsActive = true;
          optionOneIsActive = false;
          formOptionController = formBlocWatcher.buttonName;
          break;
      }
    }

    return Container(
      padding: EdgeInsets.only(
          bottom: MediaQuery.of(context).viewInsets.bottom,
          top: 15,
          left: 15,
          right: 15),
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          TextField(
            controller: nameController,
            decoration: const InputDecoration(hintText: 'Name'),
          ),
          const SizedBox(height: 10),
          TextField(
            controller: priceController,
            keyboardType: TextInputType.number,
            decoration: const InputDecoration(hintText: 'Price'),
          ),
          const SizedBox(height: 15),
          OptionsWidget(),
          Visibility(
              visible: optionOneIsActive,
              child: TextField(
                controller: formOneController,
                keyboardType: TextInputType.number,
                decoration: const InputDecoration(hintText: 'Form one'),
              )),
          Visibility(
              visible: optionTwoIsActive,
              child: Column(
                children: [
                  TextField(
                    controller: formTwoController,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(hintText: 'Form two'),
                  ),
                  TextField(
                    controller: formThreeController,
                    keyboardType: TextInputType.number,
                    decoration: const InputDecoration(hintText: 'Form three'),
                  ),
                ],
              )),
          const SizedBox(height: 10),
          ElevatedButton(
            onPressed: () {
              BlocProvider.of<ProductsListBloc>(context).add(
                AddProductEvent(
                  productName: nameController.text,
                  productPrice: int.parse(priceController.text),
                  productDescOne: formOneController.text,
                  productDescTwo: formTwoController.text,
                  productDescThree: formThreeController.text,
                  formOption: formOptionController,
                ),
              );
            },
            child: Text('Create New'),
          ),
        ],
      ),
    );
  }
}

class OptionsWidget extends StatelessWidget {
  OptionsWidget({super.key});

  int value = 0;

  Widget CustomRadioButton(String text, int index, BuildContext context) {
    final formBloc = BlocProvider.of<FormBloc>(context);
    final blocWatch = context.watch<FormBloc>().state;

    if (blocWatch is RadioButtonFormState) {
      value = blocWatch.buttonIndex;
    }
    return OutlinedButton(
        onPressed: () {
          formBloc.add(RadioButtonFormEvent(
            buttonIndex: index,
            buttonName: text,
          ));
        },
        style: OutlinedButton.styleFrom(
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
          side: BorderSide(color: (value == index) ? Colors.blue : Colors.grey),
        ),
        child: Text(
          text,
          style: TextStyle(
            color: (value == index) ? Colors.blue : Colors.grey,
          ),
        ));
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        CustomRadioButton("option one", 0, context),
        const SizedBox(width: 15),
        CustomRadioButton("option two", 1, context),
      ],
    );
  }
}
dldeef67

dldeef671#

您的FormInput类别应该是从StatefulWidget延伸,而不是从StatelessWidget延伸。
进行此更改后,您应该从build()方法中删除所有TextEditingController赋值,并将它们移到initState()中.

相关问题