flutter - Flutter:如何从自定义 StatefulWidget 中的 TextEditingController 检索文本?
问题描述
我正在尝试使自定义有状态小部件在颤动中工作。它称为 LetterTextForm,包含一些布局自定义和一个 TextField。
我希望很容易检索输入到小部件的 TextField 中的文本,在小部件主体中使用某种返回 TextEditingController.text 的 getter 方法。问题是,当我使 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,
decoration: InputDecoration(
prefixIcon: widget.prefixIcon,
labelText: widget.label,
)
);
}
}
有没有办法做到这一点,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
}
},
);
}
}
PS 如果要使用TextFormField
,则不需要控制器,您可以initialData
用于初始化。
推荐阅读
- multithreading - 为什么自旋解锁不需要刷新 x86/amd64 上的存储缓冲区
- python - 从 ray 获取结果时出现 PicklingError
- node.js - Mongoose $lookup 中嵌套对象数组的问题
- javascript - 将鼠标位置转换为画布坐标并返回
- javascript - 反应路由器重定向不渲染
- git - 使用 Maven 程序集插件创建一个存档,然后将其存储在项目中,然后标记项目在 Jenkins 中进行发布
- notion-api - 向页面或数据库页面添加提醒
- python - 用于 Python 中分层的布尔掩码,如 Matlab 中
- java - 如何在流口水决策表中将公式作为条件传递
- amazon-web-services - 无法使用 https 通过 EC2 上的画面进行连接