Flutter:如何从自定义 StatefulWidget 中的 TextEditingController 检索文本?

问题描述

我正在尝试使自定义有状态小部件在颤振中工作。它称为 LetterTextForm,包含一些布局自定义一个 TextField。

我希望可以轻松检索输入到小部件 TextField 中的文本,在小部件主体中使用某种 getter 方法返回 TextEditingController.text。问题是,当我使 TextEditingController 控制器成为这样的最终变量时:

class LetterTextForm extends StatefulWidget {

  LetterTextForm({@required this.label,this.prefixIcon});
  final Widget prefixIcon;
  final String label;
  final TextEditingController controller = TextEditingController();
  String get textEntered => controller.text;


  @override
  _LetterTextFormState createState() => _LetterTextFormState();
}

class _LetterTextFormState extends State<LetterTextForm> {
  

  @override
  void initState() {
    super.initState();
  }

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


  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: widget.controller,decoration: Inputdecoration(
          prefixIcon: widget.prefixIcon,labelText: widget.label,)
    );
  }
}


抛出以下错误: “一个 TextEditingController 被处理后使用。”

我想问题可能在于控制器不应该是最终的,所以我将控制器移到了状态类中,并在状态类中创建了一个函数 textCallback,它修改了小部件中的非最终字符串班级。这种方式有效但违反了小部件不变性:


class LetterTextForm extends StatefulWidget {

  LetterTextForm({@required this.label,this.prefixIcon});
  final Widget prefixIcon;
  final String label;
  String text = '';

  String get textEntered => text;



  @override
  _LetterTextFormState createState() => _LetterTextFormState();
}

class _LetterTextFormState extends State<LetterTextForm> {
  var controller = TextEditingController();
  
  void textCallback() {
    widget.text = controller.text;
  }

  @override
  void initState() {
    super.initState();
  }

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


  @override
  Widget build(BuildContext context) {
    return TextField(
      controller: controller,)
    );
  }
}


有没有一种方法可以做到 1) 不违反不变性和 2) 在用户按下 Enter 键时不立即处理 TextEditingController()?

当我摆脱 dispose() 方法时它会起作用,但似乎它可能会在以后导致一些性能/内存效率问题。也许我不知道我在说什么...

也许我应该尝试一些完全不同的东西,并将 TextEditingControllers 与 LetterTextForm 小部件的祖先一起放置在树中更远的位置,而不是在小部件内部?

解决方法

创建一个 ValueChanged<String> 回调成员,并在数据完成时回调。

class LetterTextForm{
  ...
  final ValueChanged<String> onChanged;
  ...
}

class _LetterTextFormState extends ... {
  final _controller = TextEditingController();
  
  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(...) {
    return TextField(
      controller: _controller,onSubmitted: (value) {
        if (widget.onChanged != null) {
          widget.onChanged(value); // returns entered value to caller
        }
      },);
  }
}

附言如果使用 TextFormField 则不需要控制器,您可以使用 initialData 进行初始化。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...