【问题标题】:A TextEditingController was used after being disposed. Called a reusable entry field class where i am passing this controller处置后使用了 TextEditingController。称为可重用的输入字段类,我在其中传递此控制器
【发布时间】:2021-06-15 16:47:41
【问题描述】:

我创建了一个可重用字段,调用该字段以在我的应用程序的不同屏幕中显示表单中的不同字段它崩溃了。

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),
      ],
    ),
  );
}

【问题讨论】:

  • 你为什么要在那个类而不是你最初创建它的类中处理控制器?
  • 我将控制器放置在可重用的小部件中,我一次又一次调用哪个类来生成不同的字段。
  • 我也尝试在我调用这个可重用类的类中进行处理,但仍然显示相同的错误
  • 很抱歉,您必须给我们一个更小、可重现的代码,以便我们尝试重现您的问题并为您提供帮助。事实上,您有很多我们无法访问的东西。
  • 我已经分享了我使用这些可重用字段的整个班级

标签: flutter android-studio dart texteditingcontroller


【解决方案1】:

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

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

所以

  • 如果控制器是全局控制器,请不要释放它们
  • 或从同一个“所有者”对象创建和处置它们

【讨论】:

  • 这是我调用这个可重用输入字段类的一个类,但我的应用程序中有许多表单,我使用这个类,我应该处理它还是不处理它
  • @InformativeProgrammer 您应该在不再需要它时将其丢弃。处理完后,如果需要再次使用,则需要创建一个新的控制器。因此,如果您打算在整个应用程序中使用同一个控制器,则无需将其丢弃。
  • 对于包含表单的不同屏幕,我使用不同的控制器,如果我尝试处理它们,则会显示错误
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 2020-10-31
  • 2011-11-21
  • 2023-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多