我正在尝试在无状态小部件中使用TextFormField以及ScopedModel来处理其中的文本,并面临以下各种问题。
我尝试将控制器用于字段,但是每次我输入一些文本并在键盘上按完成时,都会清除文本。不知道为什么。
如果我删除控制器,文本将保留在字段中,但是会出现新的问题,即如何从字段中获取文本。我使用回调 onFieldSubmitted 解决了它。
但是事实证明,只有在我们单击键盘上的完成按钮时,才会调用 onFieldSubmitted 。如果我在字段中输入文本,而不是单击“确定”,则单击另一个字段,则不会调用回调,并且我也无法跟踪用户在字段中输入的内容。
有什么解决办法吗?
附加示例代码。
class LoginPageStateless extends StatelessWidget {
final loginUsernameController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomPadding: true,
body: ScopedModelDescendant<AccountModel>(
builder: (context, child, model) {
return Form(
//key: _formKey,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Email id',
hintText: 'johndoe@ipropal.com',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
),
TextFormField(
style: TextStyle(fontSize: 15.0),
decoration: InputDecoration(
labelText: 'Password',
),
controller: loginUsernameController,
onFieldSubmitted: model.updateLoginUsernameText,
obscureText: true,
),
],
),
);
},
),
);
}
}
答案 0 :(得分:7)
您不能也不应使用Stateless
小部件来存储长期变量。
问题是,这正是您要尝试的。 TextEditingController
是应该在渲染之间保留的类实例。但是通过将其存储到StatelessWidget
中,您基本上可以在每次更新后重新创建它。
您应该将窗口小部件转换为Stateful
。并将该控制器移至State
部分
答案 1 :(得分:2)
到目前为止,我还没有使用过TextFormField,因为它的简单性和灵活性,我一直使用TextField()。使用Redux和无状态窗口小部件时遇到了类似的问题,因为我在顶层存储中只有一个真实来源。因此,我必须在ViewModel中创建一些回调,然后将该回调分配给带有字符串参数的文本字段回调'onChanged'。
public class Dispenser extends Thread {
List<Player> players = GameManager.getInstance().getRegisteredPlayers();
public void run() {
while (true) {
System.out.println("alive");
try {
for (Player p : players) {
p.setAlk(p.getAlk() + p.getDifficulty()); // TODO too hard
}
} catch (ConcurrentModificationException e) {
System.out.println("playerlist in use, retry");
}
try {
sleep(1000); // TODO too short
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
}
在包裹在小部件中的TextField中(不提供更多详细信息)
CustomTextWidgetWrapper(
onChangedCallback: viewModel.onChanged
),
然后在视图模型中,我获取字符串并将其分派到中央存储,以便在其他小部件中重用,例如获取数据并发送到服务器的按钮
new TextField(
controller: myController, // no use practically now
onChanged: onChangedCallback,
答案 2 :(得分:0)
您不能使用无状态小部件来存储长期变量。
让我们假设您有一个基本行为,例如当用户点击键盘将关闭的任何位置时,在无状态小部件中这是不可能的,因为每次打开或关闭键盘时,它都会重建并创建文本控制器的新实例,
因此在这种情况下,必须使用有状态小部件并将控制器放在状态类中