TextEditingController 被废弃后被使用

BeH*_*ppy 5 flutter

我创建了一个容器输入的表单。我循环遍历输入列表来创建表单。我的变量是:

List fields = [
    {
        'label': Strings.firstName,
        'controller': _fnameController,
        'validator': (val) => Validation.mustFilled(val),
    },
    {
        'label': Strings.lastName,
        'controller': _lnameController,
        'validator': (val) => Validation.mustFilled(val),
    },
    {
        'label': Strings.phoneNumber,
        'controller': _mobileController,
        'validator': (val) => Validation.mobile(val),
    },
];
Run Code Online (Sandbox Code Playgroud)

和我的 TextEditingController 定义:

static TextEditingController _fnameController = TextEditingController();
static TextEditingController _lnameController = TextEditingController();
static TextEditingController _mobileController = TextEditingController();
Run Code Online (Sandbox Code Playgroud)

我从上一个屏幕获取输入值并在 initState 中设置输入:

@override
void initState() {
    super.initState();
    _fnameController.text = widget.userProfile.firstName;
    _lnameController.text = widget.userProfile.lastName;
    _mobileController.text = widget.userProfile.phoneNumber;
}

for (var item in fields)
    Container(
        margin: EdgeInsets.symmetric(vertical: 10.0),
        child: Input(
            controller: item['controller'],
            label: item['label'],
            validator: item['validator'],
        ),
    ),
Run Code Online (Sandbox Code Playgroud)

和我的输入小部件:

class Input extends StatelessWidget {
  final String label;
  final VoidFunc validator;
  final TextEditingController controller;
  Input({this.label, this.validator, this.controller});
  @override
  Widget build(BuildContext context) {
    return TextFormField(
      autovalidate: true,
      controller: controller,
      textAlignVertical: TextAlignVertical.center,
      cursorColor: ColorPalette.secondary_3_5,
      decoration: InputDecoration(
        filled: true,
        labelText: label,
      ),
      validator: (value) => validator(value),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

最后处理它们:

@override
void dispose() {
    _fnameController.dispose();
    _lnameController.dispose();
    _mobileController.dispose();
    super.dispose();
}
Run Code Online (Sandbox Code Playgroud)

一切正常,但是当我导航到上一个屏幕(使用后退按钮)然后再次来到此屏幕时,我收到此错误:

A TextEditingController was used after being disposed.

Once you have called dispose() on a TextEditingController, it can no longer be used.
The relevant error-causing widget was
Run Code Online (Sandbox Code Playgroud)

小智 41

此解决方案仅适用于使用“ pin_code_fields ”依赖项的人:

添加或更改为this.autoDisposeControllers = truethis.autoDisposeControllers = false

希望能帮助到你。


chu*_*han 6

请从更改中删除static关键字TextEditingController

static TextEditingController _fnameController = TextEditingController();
static TextEditingController _lnameController = TextEditingController();
static TextEditingController _mobileController = TextEditingController();
Run Code Online (Sandbox Code Playgroud)

TextEditingController _fnameController = TextEditingController();
TextEditingController _lnameController = TextEditingController();
TextEditingController _mobileController = TextEditingController();
Run Code Online (Sandbox Code Playgroud)

我使用以下完整代码来重现此错误。

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    title: 'Navigation Basics',
    home: FirstRoute(),
  ));
}

class FirstRoute extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('First Route'),
      ),
      body: Center(
        child: ElevatedButton(
          child: Text('Open route'),
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => SecondRoute()),
            );
          },
        ),
      ),
    );
  }
}

class SecondRoute extends StatefulWidget {
  @override
  _SecondRouteState createState() => _SecondRouteState();
}

class _SecondRouteState extends State<SecondRoute> {
  static TextEditingController _fnameController = TextEditingController();

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("Second Route"),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: Text('Go back!'),
        ),
      ),
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 它并不能解决这个问题。 (8认同)