我想构建一个表单,其中我有多个 TextField
小部件,并希望通过传递从这些字段收集的数据,在按下时有一个组合和发送电子邮件的按钮 .
为此,我开始构建 InheritedWidget
以包含 TextField
-s,并基于构造函数中传递的操作 - 下面的代码中尚未包含的功能 - 它将返回来自via toString
方法覆盖的不同文本 .
据我所知,只要它是当前Widget树的一部分, InheritedWidget
就会保持它的值(例如,如果我从表单导航它会被破坏并且值丢失) .
这是我使用InheritedWidget构建TextForm的方法:
class TextInheritedWidget extends InheritedWidget {
const TextInheritedWidget({
Key key,
this.text,
Widget child}) : super(key: key, child: child);
final String text;
@override
bool updateShouldNotify(TextInheritedWidget old) {
return text != old.text;
}
static TextInheritedWidget of(BuildContext context) {
return context.inheritFromWidgetOfExactType(TextInheritedWidget);
}
}
class TextInputWidget extends StatefulWidget {
@override
createState() => new TextInputWidgetState();
}
class TextInputWidgetState extends State<TextInputWidget> {
String text;
TextEditingController textInputController = new TextEditingController();
@override
Widget build(BuildContext context) {
return new TextInheritedWidget(
text: text,
child: new TextField(
controller: textInputController,
decoration: new InputDecoration(
hintText: adoptionHintText
),
onChanged: (text) {
setState(() {
this.text = textInputController.text;
});
},
),
);
}
@override
String toString({DiagnosticLevel minLevel: DiagnosticLevel.debug}) {
// TODO: implement toString
return 'Név: ' + text;
}
}
这是启动电子邮件发送的按钮:
TextInputWidget nameInputWidget = new TextInputWidget();
TextInheritedWidget inherited = new TextInheritedWidget();
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title: new Text('Örökbefogadás'),
),
body: new Container(
padding: const EdgeInsets.all(5.0),
child: new ListView(
children: <Widget>[
new Text('Név:', style: infoText16BlackBold,),
nameInputWidget,
new FlatButton(onPressed: () {
launchAdoptionEmail(nameInputWidget.toString(), 'kutya');
},
child: new Text('Jelentkezem'))
],
),
),
);
}
我的问题是 nameInputWidget.toString()
只返回TextInputWidget(类名),我似乎无法找到访问 TextInputWidgetState.toString()
方法的方法 .
我知道 TextInheritedWidget
正确地保存了 text
值,但我不确定如何通过我的 nameInputWidget
对象访问它 .
不应该 TextInputWidget
能够通过 InheritedWidget
用来确定哪个 Widget
更新并存储值的上下文来访问数据?
2 回答
在Rémi的讲话之后,我想出了一个有效的解决方案,虽然我很确定它不是最好的,不能大规模地遵循,但应该适用于几个领域 .
解决方案是在一个单独的
State
中处理所有TextField
小部件,以及电子邮件组合 .为了实现相对干净的代码,我们可以使用自定义函数来构建具有适当数据标签的输入字段,该标签接受两个输入参数:
String
和TextEditingController
.label
还用于确定setState()
方法将传递新提交的文本的变量 .问题显然是你需要一个新的TextEditingController和一个新的String来存储你希望用户输入的每个新输入:
如果您有很多字段,这将导致很多额外的行,并且您还必须相应地更新
composeEmail()
方法,并且您拥有的字段越多,您就越有可能忘记一对 .最后,是时候构建表单了:
为方便起见,我只是在测试时将电子邮件正文打印到控制台
所有这些都在一个
State
中处理 .这是不可能的 . Only children of an InheritedWidget can access it's properties
解决方案是将
InheritedWidget
放在Button
之上 . 但这意味着你必须重构才能考虑到这一点 .