【发布时间】:2020-02-06 23:37:40
【问题描述】:
我在“页面”上有一个 TextField。我有一个 TextEditingController 连接到它。我可以通过以下简单的方法成功设置 TextField 的值:
usernameController.text = '1234';
但是,我需要能够从子页面更改此字段。用例是用户从应用程序内部注销的登录表单。当我返回登录页面时,我希望清除/删除用户名/密码。现在,值仍然存在(显示当前在 usernameController.text 中的任何内容)
总的来说,我正在通过 Provider 管理状态。我可以毫无问题地在我的应用程序的其他地方设置和检索/显示状态。问题在于控制器是通过 initState() 中的 dart 代码设置的。它不是重建的小部件的一部分。
我可以在消费者中设置 TextField 小部件。当子页面中的状态更新时调用构建器(通过调试打印语句确认),但小部件本身不反映状态的新值(它仍然具有旧用户名,并且没有被空白)。
Consumer<myAppState>(
builder: (context, appState, child) {
print("in builder for consumer: ");
print(appState.username);
return Container(
width: 200,
child: TextField(
controller: usernameController,
onChanged: (value) => _saveUsername(value),
decoration: InputDecoration(
hintText: 'Username',
prefixIcon: Icon(Icons.account_circle),
),
));
}),
我试过替换
usernameController.text = '1234';
与:
usernameController.text = Provider.of<myAppState>(context, listen: true).username;
但这似乎不起作用。
似乎这个“非纯”小部件(因为控制器正在以编程方式处理)在想要重绘小部件的消费者模型中并不漂亮。
大家有什么想法吗?
谢谢!
【问题讨论】:
-
你想做什么
usernameController.text = Provider.of<myAppState>(context, listen: true).username; -
@HemanthRaj - 我尝试在 initState() 中进行调用,以便在“登录”页面加载后立即执行。我在文档中没有看到“listen:true”实际上创建了任何类型的监听器,当 notifyListeners() 被调用时会得到通知。我只是在尝试“在黑暗中射击”适应我在其他地方看到的代码。
-
添加
initState不会成功。您可能需要更新builder中的值。 -
@HemanthRaj - 我相信我在消费者的构建器中尝试过(设置 usernameController.text = Provider.of
(context, listen: true).username;) 并且它抛出了一个异常,因为它是“在重绘已经发生时设置一个标志来重绘一个小部件”或类似的东西。我忘记了确切的术语,但如果有帮助,我可以查一下。 -
当我尝试在 builder() 中使用 setState() 时发生了关于“重绘”错误的评论。如果我尝试直接分配 usernameController.text 它不会抛出错误,但分配似乎没有发生。有关更多详细信息,请参阅您建议的答案中的 cmets。谢谢!