0

我创建了一个可重用字段,该字段被调用以在我的应用程序的不同屏幕中显示表单中的不同字段我还传递了一个控制器,但是当处置控制器时它会显示此错误,如果我回到同一个表单屏幕它会崩溃。

class EntryField extends StatefulWidget {
  @override
  _EntryFieldState createState() => _EntryFieldState();
  final String title;
  final TextEditingController controller;
  final TextInputType inputType;
  final FilteringTextInputFormatter filter;
  final hintText;
  EntryField({@required this.title,this.hintText,@required this.controller,@required this.inputType,@required this.filter});
}
class _EntryFieldState extends State<EntryField> {
  @override
  void dispose() {
    widget.controller.dispose();
    print("anything");
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.symmetric(vertical: 10),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          Text(
              this.widget.title,
              style: GoogleFonts.quicksand(
                fontSize: 18,
              )
          ),
          SizedBox(
            height: 10,
          ),
          TextFormField(
            controller: this.widget.controller,
            keyboardType: this.widget.inputType,
            inputFormatters: <TextInputFormatter>[
              this.widget.filter,
            ],
            validator: (value){
              if(value.isEmpty){
                return "${this.widget.title} is a Required Field";
              }
              return null;
            },
            decoration: InputDecoration(
              hintText: this.widget.hintText,
              border: InputBorder.none,
              fillColor: Color(0xfff3f3f4),
              filled: true,
              errorBorder: new OutlineInputBorder(
                borderSide: new BorderSide(color: Colors.red),
              ),
              errorStyle: TextStyle(
                fontSize: 15,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

在这个类中,我正在传递它的字段值

final GlobalKey<FormState> _formKey = GlobalKey<FormState>();
final _serviceTitleController = TextEditingController();
final _serviceCategoryController = TextEditingController();
final _servicePriceController = TextEditingController();
ToastErrorMessage _error = ToastErrorMessage();
ToastValidMessage _valid = ToastValidMessage();

class AddServices extends StatefulWidget {
  @override
  _AddServicesState createState() => _AddServicesState();
}

class _AddServicesState extends State<AddServices> {

  int currentIndex;
  String _cityName;
  final WorkshopServiceQueries _add = WorkshopServiceQueries();
  final _firebaseUser = FirebaseAuth.instance.currentUser;

  @override
  void initState() {
    cityName();
    super.initState();
    currentIndex = 0;
  }
  @override
  void dispose() {
    print("hello");
    super.dispose();
  }
  void clearControllerText(){
    _serviceTitleController.clear();
    _serviceCategoryController.clear();
    _servicePriceController.clear();

  }

  Future cityName() async{
   _cityName = await _add.getWorkshopCityName();
  }

  changePage(int index) {
    setState(() {
      currentIndex = index;
    });
  }
  validateFields() async{

    final ValidateWorkshopServices service = ValidateWorkshopServices();
    final int _price = int.tryParse(_servicePriceController.text.trim());
    if(!service.validateServiceCategory(_serviceCategoryController.text.trim()) && !service.validateServiceTitle(_serviceTitleController.text.trim()) && !service.validateServicePrice(_price)){
      _error.errorToastMessage(errorMessage: "Enter Valid Data in Each Field");
    }
    else if(!service.validateServiceCategory(_serviceCategoryController.text.trim())){
      _error.errorToastMessage(errorMessage: "Service Category Must Only contain Alphabets");
    }
    else if(!service.validateServiceTitle(_serviceTitleController.text.trim())){
      _error.errorToastMessage(errorMessage: "Service Title Must Only contain Alphabets");
    }
    else if(!service.validateServicePrice(_price)){
      _error.errorToastMessage(errorMessage: "Service Price must be less than or equal to 2000");
    }
    else{
     await addService(_price);
    }
  }
  Future<void> addService(int price) async{
  try {

      Services data = Services(title: _serviceTitleController.text.trim(), category: _serviceCategoryController.text.trim(), price: price, workshopCity: _cityName, workshopId: _firebaseUser.uid);
      await _add.addWorkshopService(data);
      if(WorkshopServiceQueries.resultMessage == WorkshopServiceQueries.completionMessage){
        _valid.validToastMessage(validMessage: WorkshopServiceQueries.resultMessage);
        clearControllerText();
        Future.delayed(
          new Duration(seconds: 2),
              (){
            Navigator.pop(context);
          },
        );
      }
      else{
        _error.errorToastMessage(errorMessage: WorkshopServiceQueries.resultMessage);
      }
    }catch(e){
       _error.errorToastMessage(errorMessage: e.toString());
    }
}

  @override
  Widget build(BuildContext context) {

    final height = MediaQuery.of(context).size.height;
    int _checkboxValue;
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text(
            'BIKERSWORLD',
            style: GoogleFonts.quicksand(
              color: Colors.white,
              fontSize: 18,
            ),
          ),
          backgroundColor: Color(0XFF012A4A),
            leading: IconButton(icon:Icon(Icons.arrow_back, color: Colors.orange,),
              onPressed:() => Navigator.pop(context),
            )
        ),
        body: Container(
          height: height,
          child: Stack(
            children: <Widget>[
              Container(
                padding: EdgeInsets.symmetric(horizontal: 20),
                child: SingleChildScrollView(
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      SizedBox(height: 30,),
                      _title(),
                      SizedBox(height: 40),
                      _addServicesWidget(),
                      SizedBox(height: 20),
                      FlatButton(
                      child: Container(
                        padding: EdgeInsets.symmetric(vertical: 15),
                        alignment: Alignment.center,
                        decoration: BoxDecoration(
                            borderRadius: BorderRadius.all(Radius.circular(5)),
                            boxShadow: <BoxShadow>[
                              BoxShadow(
                                  color: Colors.grey.shade200,
                                  offset: Offset(2, 4),
                                  blurRadius: 5,
                                  spreadRadius: 2)
                            ],
                            gradient: LinearGradient(
                                begin: Alignment.centerLeft,
                                end: Alignment.centerRight,
                                colors: [Color(0xfffbb448), Color(0xfff7892b)])),
                        child: Text(
                          'Register Now',
                          style: GoogleFonts.krub(
                            fontSize: 18,
                            color: Colors.white,
                          ),
                        ),
                      ),
                      onPressed: (){
                        if(!_formKey.currentState.validate()){
                          return;
                        }
                        else{
                          validateFields();
                        }
                      },
                    ),
                      SizedBox(height: 20),

                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Widget _addServicesWidget() {
  return Form(
    key: _formKey,
    autovalidateMode: AutovalidateMode.disabled,
    child: Column(
      children: <Widget>[
        EntryField(title: "Category",hintText: 'Mechanical',controller: _serviceCategoryController,inputType: TextInputType.text,filter: FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))),
        SizedBox(height:15,),
        EntryField(title: "Title",hintText: 'wheel barring',controller: _serviceTitleController,inputType: TextInputType.text,filter: FilteringTextInputFormatter.allow(RegExp("[a-zA-Z ]"))),
        SizedBox(height:15,),
        EntryField(title: "Price",hintText: 'price < 2000',controller: _servicePriceController,inputType: TextInputType.number,filter:FilteringTextInputFormatter.digitsOnly),
      ],
    ),
  );
}
4

1 回答 1

2

您不应该在小部件内处理控制器,因为您是在小部件外部创建它并将对它的引用传递到小部件中。

看起来您的控制器是在全局范围内创建的 - 如果是这样,并且如果它们打算在应用程序的整个生命周期中使用,则不应处置它们。

所以要么

  • 如果它们是全局控制器,请不要处理它们
  • 或从同一个“所有者”对象创建和处置它们
于 2021-03-18T12:02:06.847 回答